iPad定制尺寸的模态视图控制器

时间:2010-07-21 10:49:02

标签: ipad uiviewcontroller modalviewcontroller

我有一些特定尺寸的模态视图控制器。我试图避免使用自定义视图(在当前视图上创建全屏黑色半透明覆盖,在该视图上添加模态视图,执行动画等)来呈现它,因为没有适合我的大小的modalPresentationStyle控制器。

现在我正在使用UIModalPresentationPageSheet,但我的视图高度较小,而且我的空白空间很难

期望的演示文稿

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

实际演示

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

如果我使用UIModalPresentationFormSheet,则容器的宽度会变小。

我正在试图弄清楚如何做,但我不知道是否可能。呈现比任何presentationStyles更小的模态VC的问题的解决方案是什么?唯一的解决方案是安排“自定义模态视图控制器引擎”?弹出装置不符合我的设计要求:(

12 个答案:

答案 0 :(得分:35)

我使用:

获得了以下结果(link text
self.modalPresentationStyle = UIModalPresentationFormSheet;

并将其呈现为模态视图控制器。如果您需要进一步的帮助,请告诉我。

答案 1 :(得分:24)

所有这些答案都不适用于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,它为您提供更多自定义选项。

答案 2 :(得分:19)

我有一个问题是让自定义大小的模式居中,直到我弄清楚最初设置的ViewController.view.superview.frame。它是根据UIModalPresentation类型确定的。甚至不需要superview.center(据我的测试显示)。

另外,我使用[UIScreen mainScreen].applicationFrame动态设置坐标,目前只支持横向。您必须通过翻转X / Y和高度/宽度值来进行条件检查以支持纵向和横向。

这是我的第一个适用于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);

编辑以获得最终解决方案和备注。

答案 3 :(得分:18)

执行此操作的最佳方法是更改​​表单内显示的视图的超级视图的bounds属性。当您以模态方式呈现视图时,呈现的视图将嵌入到另一个视图中。

您应该将superview的bounds属性设置为与视图边界相同的rect。首先在班上添加私人ivar:

@implementation MySpecialFormsheet {
    CGRect _realBounds;
} 

最好在viewWillAppear:中执行此操作。将以下代码添加到以模态方式呈现的视图控制器中:

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

您需要在_realBounds方法中缓存viewDidLoad

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

答案 4 :(得分:7)

这是我的自动布局视图的解决方案(从未尝试使用自动布局)并且符合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 

答案 5 :(得分:6)

即使减少地层板的高度和宽度,也可以使用

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

答案 6 :(得分:5)

上述方法需要针对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。)

答案 7 :(得分:4)

即使我在相同的问题上挣扎了很长一段时间。在从这里给出的许多答案中尝试几次之后,我提出了一个对我很有用的解决方案。

这是展示视图控制器时的代码。

    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

在“模拟指标”部分的xib中(如果您使用的是xib)选择“自由形式”尺寸。

除此之外,您需要在您呈现的视图控制器中编写以下代码(即..,本例中的SomeViewController)

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

}

此代码也适用于iOS 7

答案 8 :(得分:3)

一种解决方案是使用UIModalPresentationPageSheet显示页面表,然后立即调整模式视图的大小。这在this answer to another question

中有详细解释

答案 9 :(得分:1)

使用presentModalViewController方法显示“之后”调整模式视图的大小。请参阅此链接以调整模式视图https://coderwall.com/p/vebqaq

答案 10 :(得分:1)

您可以像这样使用MZFormSheetController

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

答案 11 :(得分:0)

这个解决方案对我有用,因为我有同样的问题。

我的模态视图结构如下(我在呈现和呈现的控制器上使用UIModalPresentationCurrentContext来实现所呈现的VC的透明度)

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);
}

我实际上首先使用不同的方法创建内容视图并调整其大小。

希望这有助于某人。