web-dev-qa-db-ja.com

iPadのモーダルビューコントローラーのカスタムサイズ

特定のサイズのモーダルビューコントローラーがいくつかあります。私のサイズに合ったmodalPresentationStyleがないため、カスタムビュー(現在のビューの上にフルスクリーンの黒い半透明のオーバーレイを作成し、そのビューの上にモーダルビューを追加し、アニメーションを実行するなど)の使用を避けようとしていますコントローラー。

今私はUIModalPresentationPageSheetを使用していますが、私のビューは高さが小さく、い空白スペースがあります

希望するプレゼンテーション

 _______________
|    _______    |
|   |       |   |
|   |  MyVC |   |
|   |       |   |
|    -------    |
 --------------- 

実際のプレゼンテーション

 _______________
|   |       |   |
|   |  MyVC |   |
|   |       |   |
|   |-------|   |
|   | blank |   |
 ---------------    

UIModalPresentationFormSheetを使用すると、コンテナーの幅が小さくなります。

私はそれを行う方法を理解しようとしていますが、それが可能かどうかはわかりません。モーダルを提示する問題の解決策は何ですかVC presentationStylesのいずれよりも小さいですか?唯一の解決策は、「カスタムモーダルビューコントローラエンジン」を配置することですか?Popoversは私の設計に適合しません要件:(

54
emenegro

他のユーザーとして、モーダルビューコントローラーのOriginが正しくないという問題もありました。いくつかの実験の後、私のために働いた解決策を見つけました:

- (void)viewWillLayoutSubviews{
    [super viewWillLayoutSubviews];   
    self.view.superview.bounds = CGRectMake(0, 0, <width>, <height>);
}
84
Lensflare

次を使用して、次の結果を得ました( link text ):

self.modalPresentationStyle = UIModalPresentationFormSheet;

モーダルビューコントローラーとして表示することにより。さらにサポートが必要な場合はお知らせください。

35
marcio

これらの答えはすべて、ios8 SDKでは機能しません。

これは動作します:

AboutViewController * _aboutViewController = [[AboutViewController alloc] init];
    _aboutViewController.modalPresentationStyle = UIModalPresentationFormSheet;
    if(IS_IOS8)
    {
        _aboutViewController.preferredContentSize = CGSizeMake(300, 300);
    }
    [self presentViewController:_aboutViewController animated:YES completion:nil];

AboutViewController.mで

- (void)viewWillLayoutSubviews{
    [super viewWillLayoutSubviews];

    if(!IS_IOS8)
    {
        self.view.superview.bounds = CGRectMake(0, 0, 300, 300);
    }
}

IS_IOS8

#define IS_IOS8 ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8)

IOS 8では、より多くのカスタマイズオプションを提供するUIPresentationControllerを使用することもできます。

24
pawel_d

ViewController.view.superview.frameが最初に設定されているものがわかるまで、カスタムサイズのモーダルを中央に配置するのに問題がありました。 UIModalPresentationタイプに基づいて決定されます。 superview.centerは必要ありません(私のテストが示す限り)。

また、[UIScreen mainScreen].applicationFrameを使用して動的に座標を設定しますが、現時点では横向きのみをサポートしています。 X/YとHeight/Widthの値を反転することにより、ポートレートとランドスケープの両方をサポートする条件付きチェックを行う必要があります。

IOS 6.0向けの最初の実用的なソリューションは次のとおりです。

ViewController.modalPresentationStyle = UIModalPresentationFormSheet;
ViewController.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
[self presentViewController:ViewController animated:YES completion:nil];
ViewController.view.superview.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin;
ViewController.view.superview.frame = CGRectMake(
                                                                    // Calcuation based on landscape orientation (width=height) 
                                                                    ([UIScreen mainScreen].applicationFrame.size.height/2)-(320/2),// X
                                                                    ([UIScreen mainScreen].applicationFrame.size.width/2)-(320/2),// Y
                                                                    320,// Width
                                                                    320// Height
                                                                    );

そして、私は前の答えを見て、手のひらに直面しました。最後の行を次のように置き換えることで、ソリューションを少し短くしました:

ViewController.view.superview.bounds = CGRectMake(0, 0, 320, 320);

[〜#〜] edit [〜#〜]最終的な解決策と備考。

19
Brenden

これを行う最良の方法は、フォームシート内に表示されるビューのスーパービューの境界プロパティを変更することです。ビューをモーダルで表示すると、表示されたビューは別のビューに埋め込まれます。

スーパービューのboundsプロパティを、ビューの境界と同じ四角形に設定する必要があります。まず、クラスにプライベートivarを追加します。

@implementation MySpecialFormsheet {
    CGRect _realBounds;
} 

viewWillAppear:でこれを行うのが最善です。モーダルで表示されているView Controllerに次のコードを追加します。

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    self.view.superview.bounds = _realBounds;
}

viewDidLoadメソッドで_realBoundsをキャッシュする必要があります。

- (void)viewDidLoad {
    _realBounds = self.view.bounds;
    [super viewDidLoad];
}
18
Rob Jones

これは、自動レイアウトではないビュー(自動レイアウトで試したことがない)に対する私のソリューションであり、iOS 7およびiOS 8に準拠しています。

最初に、この方法でモーダルビューを呼び出してください:

CloudSettingsViewController *cloudController = [[CloudSettingsViewController alloc] initWithNibName:@"CloudSettingsView" bundle:nil];

CGRect originalBounds = cloudController.view.bounds;

cloudController.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
cloudController.modalPresentationStyle = UIModalPresentationFormSheet;

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

IOS 8では、モーダルビューのviewDidLoadメソッドでpreferredContentSizeを設定します。

- (void)viewDidLoad {
    [super viewDidLoad];

    // backup of the original size (selected in interface builder)
    height = self.view.frame.size.height;
    width = self.view.frame.size.width;

    if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8) // versioni successive ios 8
        self.preferredContentSize = CGSizeMake(width, height); // this is necessary to get the correct size of the modal view
}

これは、モーダルビューでiPadにキーボードを表示する必要がある場合にも機能します

IOS 8の以前のバージョンでは、presentViewControllerの呼び出し後に境界を設定する必要があります。

[currentController presentViewController:controlPanelController animated:YES completion:nil];
if ([[[UIDevice currentDevice] systemVersion] floatValue] < 8) 
    cloudController.view.superview.bounds = originalBounds;//it's important to do this after 
7
Magurizio

フォーマシートの高さと幅を縮小するためにも使用できます

[self.view.superview setBounds:CGRectMake(0, 0, 450, 480)];
6
Kasaname

上記のアプローチは、iOS7用に調整する必要があります。

// set desired bounds, then call -presentFromViewController:

@implementation PresentedViewController
{
    CGRect _presentationBounds;
}

- (void)presentFromViewController:(UIViewController *)viewController
{
    self.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
    self.modalPresentationStyle = UIModalPresentationFormSheet;

    _presentationBounds = self.view.bounds;

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

- (void)viewWillLayoutSubviews
{
    [super viewWillLayoutSubviews];

    if (!CGRectIsEmpty(_presentationBounds))
    {
        self.view.superview.bounds = _presentationBounds;
        _presentationBounds = CGRectZero;
    }
}

(このコードはiOS6でも動作します。)

5
hatfinch

私も同じ問題にかなり長い間苦労していました。ここで与えられた多くの回答から数回の試行を行った後、私はかなりうまく機能する解決策を思いつきました。

以下は、View Controllerを表示する際のコードです。

    SomeViewController *sovcObj = [[SomeViewController alloc] initWithNibName:@"SyncOptionsViewController" bundle:nil];
someObj.modalPresentationStyle = UIModalPresentationFormSheet;
someObj.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
[self presentViewController:someObj animated:YES completion:nil];
someObj.view.superview.bounds = CGRectMake(0, 0, 400, 400); // whatever width and height you want

Xim(使用している場合)の[シミュレートされたメトリック]セクションで、[フリーフォーム]サイズを選択します。

これとは別に、提示されたView Controller(つまり、この例ではSomeViewController)で以下のコードを記述する必要があります

- (void)viewWillLayoutSubviews{
[super viewWillLayoutSubviews];
self.view.superview.bounds = CGRectMake(0, 0, 400, 400); // whatever width and height you want

}

このコードはiOS 7でも機能します

4
Rajesh

1つの解決策は、UIModalPresentationPageSheetを使用してページシートを表示し、すぐにモーダルビューのサイズを変更することです。これは 別の質問に対するこの回答 で完全に説明されています。

3
Travelling Man

MZFormSheetController を次のように使用できます。

MZFormSheetController *formSheet = [[MZFormSheetController alloc] initWithSize:customSize viewController:presentedViewController];
[presentingViewController mz_presentFormSheetController:formSheet animated:YES completionHandler:nil];
1
Maxim Pavlov

PresentModalViewControllerメソッドを使用して表示された後のモーダルビューのサイズを変更します。モーダルビューのサイズを変更するには、このリンクを参照してください https://coderwall.com/p/vebqaq

1
NetDeveloper

私は同じ問題を抱えていたので、この解決策はうまくいきました。

私のモーダルビューの構造は次のとおりです(提示されたVCの透明性を実現するために、提示されたコントローラーと提示されたコントローラーの両方でUIModalPresentationCurrentContextを使用します)

ModalViewController
  > UIView (view) - resized to the same size as the presenting controller but has semi-translucent background - done automatically
      >> UIView (contentView) - the true view with the content of the popup - this is the one that got consistently placed at the top of the screen all the time

ModalViewControllerで、位置決めの問題を修正するために次のメソッドを上書きしました。

- (void) viewWillLayoutSubviews(){
  [super viewWillLayoutSubviews];

  CGRect r = self.view.bounds();
  self.contentView.center = CGPointMake(r.size.width/2,r.size.height/2);
}

最初にコンテンツビューを作成し、サイズを変更しますが、方法は異なります。

これが誰かを助けることを願っています。

0
Moonwalker