56

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

现在我正在使用 UIModalPresentationPageSheet 但我的视图高度较小而且我有一个丑陋的空白

所需的演示文稿

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

实际演示

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

如果我使用 UIModalPresentationFormSheet 容器的宽度更小。

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

4

13 回答 13

84

和这里的其他一些用户一样,我也遇到了模态视图控制器的来源不正确的问题。经过一些实验,我找到了一个适合我的解决方案:

- (void)viewWillLayoutSubviews{
    [super viewWillLayoutSubviews];   
    self.view.superview.bounds = CGRectMake(0, 0, <width>, <height>);
}
于 2013-01-23T19:39:45.747 回答
35

我通过使用获得了以下结果(链接文本):

self.modalPresentationStyle = UIModalPresentationFormSheet;

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

于 2010-08-02T08:24:42.637 回答
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,它为您提供更多自定义选项。

于 2014-09-22T07:43:01.003 回答
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);

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

于 2012-11-12T19:58:25.477 回答
18

最好的方法是更改​​表单表中显示的视图的父视图上的 bounds 属性。当您以模态方式呈现视图时,呈现的视图会嵌入到另一个视图中。

您应该将超级视图的边界属性设置为与视图边界相同的矩形。首先在你的类中添加一个私有 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];
}
于 2012-04-13T03:08:18.117 回答
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 
于 2014-09-24T12:56:06.857 回答
7

即使是为了减少表格的高度和宽度,您也可以使用

[self.view.superview setBounds:CGRectMake(0, 0, 450, 480)];
于 2012-10-11T05:25:03.260 回答
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。)

于 2013-12-05T08:47:04.953 回答
4

Even I was struggling with the same issue for quite a while. After giving few tries from many of the answers given here I came up with a solution that worked for me pretty well.

Here is the code while presenting the 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

In the xib (if you are using one) in the 'Simulated Metrics' section select 'Freeform' size.

Apart from this you need to write the below code in your presented view controller (i.e.., SomeViewController in this example)

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

}

This code also works for iOS 7 as well

于 2014-01-21T12:11:24.807 回答
3

一种解决方案是使用 UIModalPresentationPageSheet 呈现页面表,然后立即调整模式视图的大小。这在另一个问题的答案中得到了充分解释。

于 2011-02-08T17:11:47.583 回答
1

您可以像这样使用MZFormSheetController

MZFormSheetController *formSheet = [[MZFormSheetController alloc] initWithSize:customSize viewController:presentedViewController];
[presentingViewController mz_presentFormSheetController:formSheet animated:YES completionHandler:nil];
于 2015-01-22T11:02:23.173 回答
1

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

于 2013-05-02T14:41:45.787 回答
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);
}

我实际上是先创建内容视图并调整其大小,但方法不同。

希望这可以帮助某人。

于 2015-01-21T19:50:08.047 回答