5

UIViewController親のViewControllerの上を中心に、iPadでカスタムフレームを使用してモーダルを表示したいと思います。

フォームシートを使ってみましたが、フレームと影の効果は変更できないことがわかっています。

vc.modalPresentationStyle = UIModalPresentationFormSheet;
[self presentModalViewController:cv animated:YES];

私もポップオーバーを使ってみましたが、私が知る限り、それを中央に配置できないか、矢印を隠すことができません。

モーダルビューコントローラーを表示する別の方法はありますか?フォームシートやポップオーバーを使用してこの問題を解決することは可能ですか?

4

5 に答える 5

6

次の方法を使用して、画面の中央に任意のサイズのモーダルビューコントローラーを作成しています。必要に応じて、親ViewControllerの中央に変更できます。これはストーリーボードから機能しているため、代わりにViewControllerを引数として送信できます。しかし、それとは別に、それはあなたが必要とすることをします。

注:このモーダルの上に別のモーダルを表示しようとすると、元のサイズに戻ることがわかりました。

- (UIViewController *) presentModalViewControllerWithIdentifier:(NSString *)identifier 
                                                        andSize:(CGSize)size 
                                        andModalTransitionStyle:(UIModalTransitionStyle)modalTransitionStyle {
    UIViewController *viewController = [self.storyboard instantiateViewControllerWithIdentifier:identifier];


    viewController.modalPresentationStyle = UIModalPresentationPageSheet;
    viewController.modalTransitionStyle = modalTransitionStyle;
    [self presentModalViewController:viewController animated:YES];
    viewController.view.superview.autoresizingMask = 
    UIViewAutoresizingFlexibleTopMargin | 
    UIViewAutoresizingFlexibleBottomMargin | 
    UIViewAutoresizingFlexibleLeftMargin | 
    UIViewAutoresizingFlexibleRightMargin;    
    CGRect screenBounds = [[UIScreen mainScreen] bounds];
    viewController.view.superview.frame = CGRectMake(0, 0, size.width, size.height);
    CGPoint center = CGPointMake(CGRectGetMidX(screenBounds), CGRectGetMidY(screenBounds));
    viewController.view.superview.center = UIDeviceOrientationIsPortrait(self.interfaceOrientation) ? center : CGPointMake(center.y, center.x);

    return viewController;
}

それがあなたが望む唯一のものであるならば、それはうまく働きます。しかし、私が見つけたのは、Appleのモーダルビューコントローラーの実装は、その下にある部分にアクセスできず、完全にアニメートできないため、少し逆効果であるということです。独自のトランジションが必要な場合に便利です。

また、ウィンドウ内の他のすべてのビューの上にあるため、子ビューコントローラーのカテゴリにも分類されません。

于 2012-08-15T09:53:15.310 に答える
4

これを行う公式の方法はありませんが、参照または委任を保持して現在のビューコントローラと対話し、それをビュー階層に追加するカスタムビューを作成することで、目的の動作を得ることができます。モーダルな感覚を実際に得るには、「モーダル」ビューのすぐ下にある表示コントローラーの上に透明なオーバーレイを配置することもできます。私はこれを多くのアプリで行ってきましたが、通常はうまくいきます。タッチをインターセプトし、そのプレゼンテーションをよりエレガントにアニメーション化できるように、カスタムオーバーレイビューを作成する必要がある可能性があります。

私の透明なオーバーレイは通常次のようなものです:

@protocol TransparentOverlayDelegate <NSObject>

@optional
- (void)transparentOverlayWillDismiss:(TransparentOverlay *)backgroundTouch;
- (void)transparentOverlayDidDismiss:(TransparentOverlay *)backgroundTouch;
@end


@interface TransparentOverlay : UIView {

    id<TransparentOverlayDelegate> _delegate;
    UIView *_contentView;
    CGFloat _pAlpha;
}

@property(nonatomic, assign) id<TransparentOverlayDelegate> delegate;
@property(nonatomic, retain) UIView *contentView;
@property(nonatomic, assign) CGFloat pAlpha;

- (void)presentTransparentOverlayInView:(UIView *)view;
- (void)dismissTransparentOverlay:(BOOL)animated;

私のカスタムモーダルビューは通常、次のようなものです。

@protocol ModalViewDelegate <NSObject>
- (void)performSelectorOnDelegate:(SEL)selector;
@end

@interface ModalView : UIView {
    id<ModalViewDelegate> _delegate;
}

@property(nonatomic, assign) id<ModalViewDelegate> delegate;

私のプレゼンテーションビューコントローラーでは、通常、次のことを行います。

- (void)presentModalController {
    TransparentOverlay *to = [[[TransparentOverlay alloc] initWithFrame:self.view.bounds] autorelease];
    to.delegate = self;

    ModalView *mv = [[ModalView alloc] initWithFrame:CGRectMake(500, 500, 300, 300)];
    mv.delegate = self;

    to.contentView = mv;
    [mv release];

    [to presentTransparentOverlayInView:self.view]; 
}

2つのクラスで定義されたデリゲートを使用すると、プレゼンテーションコントローラーを操作したり、必要に応じてプレゼンテーションと解雇を操作したりするためのほぼオープンなアクセスが可能になります。これの唯一の欠点は、NavigationBarのあるビューで使用する場合です。これは、表示するコントローラーのビューの境界にNavigationBarの境界が含まれず、対話用に開いたままになるためです。これを回避する方法はありますが、回避する方法はありません。とてもきれいです(ナビゲーションコントローラーのビューに追加するのは1つのオプションです)。

于 2012-01-28T14:53:28.500 に答える
1

これはあなたの質問に完全には答えないかもしれません。ただし、以前にsplitviewcontrollerの詳細ビューの上部に配置したナビゲーションコントローラーのrightbuttonitemから次のコードを呼び出します。

このモーダルビューは画面全体をカバーします。たとえば、detailviewcontrollerで呼び出された場合にのみ、詳細ビューをカバーしたいですか?

- (void)aboutAction {

About *about = [[About alloc] init];
UINavigationController *nav1 = [[UINavigationController alloc]initWithRootViewController:about];
[about release];
nav1.navigationBar.barStyle = UIBarStyleBlackOpaque;
nav1.modalPresentationStyle = UIModalPresentationFullScreen;
nav1.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:nav1 animated:YES ];
[nav1 release];

}
于 2011-02-10T21:39:25.930 に答える
1

私はfabio-oliveiraの答えを好みますが、IOS 7のマルチスレッド環境で動作させるには、いくつかの調整が必要です。

- (UIViewController *)presentModalViewControllerWithId:(NSString *)identifier
                                           andSize:(CGSize)size
                           andModalTransitionStyle:(UIModalTransitionStyle)style
{
    UIViewController *viewController = 
            [self.storyboard instantiateViewControllerWithIdentifier:identifier];

    viewController.modalPresentationStyle = UIModalPresentationPageSheet;
    viewController.modalTransitionStyle = style;

    [self presentViewController:viewController animated:YES completion:nil];

    viewController.view.superview.autoresizingMask = 
        UIViewAutoresizingFlexibleTopMargin    |
        UIViewAutoresizingFlexibleBottomMargin | 
        UIViewAutoresizingFlexibleLeftMargin   | 
        UIViewAutoresizingFlexibleRightMargin;

    viewController.view.superview.frame = 
                   CGRectMake(0, 0, size.width, size.height);

   return viewController;
}

次に、新しいスレッドが機能するように、ターゲットVCにセンタリングコードを配置します。

- (void)viewWillLayoutSubviews
{
    [super viewWillLayoutSubviews];
    CGRect screenBounds = [[UIScreen mainScreen] bounds];
    CGPoint center = CGPointMake(CGRectGetMidX(screenBounds),
                                 CGRectGetMidY(screenBounds));

    self.view.superview.center =
    UIDeviceOrientationIsPortrait(self.interfaceOrientation) ? 
                                       center : CGPointMake(center.y, center.x);
}

そうです、これらの素敵なIOS 5 iPad 1をサポートしている場合は、必ずターゲットvcを回転させてください。

- (BOOL)shouldAutorotateToInterfaceOrientation:
                         (UIInterfaceOrientation)interfaceOrientation
{
    return YES;
}
于 2013-10-13T22:12:35.920 に答える
1

私の場合、オーバーライドでviewWillLayoutSubviewsうまくいきました。

- (void)viewWillLayoutSubviews {
        [super viewWillLayoutSubviews];

    self.view.superview.frame = CGRectMake(100.f, 100.f, <width>, <height>); 
}

の位置と境界を変更するために、これ以上何も必要ありませんでしたModalViewController

于 2014-07-31T19:14:25.313 に答える