为啥我的模态呈现(表单)navController 的 rootViewController 在模态呈现时不知道它的尺寸较小?

Posted

技术标签:

【中文标题】为啥我的模态呈现(表单)navController 的 rootViewController 在模态呈现时不知道它的尺寸较小?【英文标题】:Why isn't the rootViewController of my modally presented (form sheet) navController aware of it's smaller size when presented modally?为什么我的模态呈现(表单)navController 的 rootViewController 在模态呈现时不知道它的尺寸较小? 【发布时间】:2014-01-09 20:19:57 【问题描述】:

我正在开发一个带有几个不同模式视图的 iPad 应用程序,这段代码很常见:

UIViewController *v1 = [[UIViewController alloc] init];

UINavigationController *nav1 = [[UINavigationController alloc] initWithRootViewController:v1];
nav1.modalPresentationStyle = UIModalPresentationFormSheet;

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

可能是我做错了,但这就是我以模态方式呈现 navController-nested vc 的方式。

问题是在 v1 类中,任何对 self.frame/bounds 的引用都会导致全屏尺寸:768x1024。即使 navController 显然没有以该尺寸显示。

我应该怎么做才能让 v1 vc 知道它实际上有多大?这样,如果我想添加一个 tableView,它就会知道它应该有多大?

谢谢!

编辑:

我已经尝试了更多的东西,但仍然没有解决这个问题的方法。我制作了一个简单的示例项目来说明我遇到的问题。我只有一个观点,这是代码的核心:

- (void)viewDidLoad

[super viewDidLoad];

NSLog(@"Frame: %@", NSStringFromCGRect(self.view.frame));
NSLog(@"Bounds: %@", NSStringFromCGRect(self.view.bounds));

UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.frame = CGRectMake(self.view.frame.size.width - 400, 0, 400, 400);
button.backgroundColor = [UIColor redColor];
[button addTarget:self action:@selector(presentModal) forControlEvents:UIControlEventTouchUpInside];

[self.view addSubview:button];


- (void)presentModal 
SSViewController *view = [[SSViewController alloc] init];

UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:view];
nav.modalPresentationStyle = UIModalPresentationFormSheet;

[self.navigationController presentViewController:nav animated:YES completion:nil];

当这个视图加载时,我的视图右上角有一个红色的大按钮。当我按下按钮时,它会在嵌入导航控制器的模式视图中加载相同的 VC。该按钮几乎显示在屏幕外,因为框架没有改变。它仍然显示为全屏。这是link to the project。

【问题讨论】:

【参考方案1】:

不确定您遇到问题的原因。我正在使用以下代码:

- (void)presentNewView 
    NewViewController *newVC = [[NewViewController alloc] initWithNibName:nil bundle:nil];
    newVC.view.backgroundColor = [UIColor redColor];

    UINavigationController *newNC = [[UINavigationController alloc] initWithRootViewController:newVC];
    newNC.modalPresentationStyle = UIModalPresentationFormSheet;

    [self.navigationController presentViewController:newNC animated:YES completion:NULL];

.. 它会在模拟器中产生以下结果:

.. 当我打印出第一个 ViewController 的框架和边界时(我认为这可能是两者的问题),我得到以下信息:

帧高:1024.000000 框架宽度:768.000000 边界高度:1024.000000 边界宽度:768.000000

.. 当我打印出呈现的 ViewController 的框架/边界时,我得到以下信息:

帧高:620.000000 框架宽度:540.000000 边界高度:620.000000 边界宽度:540.000000

您如何准确确定框架的大小? v1 类中以模态方式呈现的任何引用应该知道它的实际大小,就像我在上面展示的那样。

编辑

我发现我的代码和你的代码的主要区别在于,在我的代码中,我创建了视图控制器“NewViewController”的子类,并从该类中打印出框架。班级本身似乎知道其正确的界限,但所呈现的班级似乎没有。这可以通过从提供它的 ViewController 类中打印视图属性来演示:

NewViewController 的展示类视图:frame = (0 0; 768 1024)

..与从 NewViewController 本身的 ViewDidAppear 方法中打印出 self.view 相比:

NewViewController 的视图出现了:frame = (0 0; 540 576)

故事的寓意,如果你要以你展示的方式呈现一个 UIViewController,你可能会想要继承 UIViewController 以便你可以随意定制它,所以在那个文件中如果您引用 self.view 或 self.bounds 您将获得 ACTUAL 视图/边界。

编辑#2

根据您提供的项目,您遇到该问题的原因是您在 viewDidLoad 中打印出视图的框架/边界,而不是 viewDid/viewWillAppear。将这些 NSLog 语句添加到 VWA 或 VDA 可以为您提供正确的框架,因此正如我在最初的编辑中所说,您应该可以在此时正确访问模态视图。

【讨论】:

感谢您的回答。我仍然无法让它正常工作。我已经编辑了我的答案以包含一个更清楚地显示问题的示例项目。谢谢! 另外,附带说明一下,看起来您的 viewController 根本没有附加导航控制器,因此我不得不稍微更改代码以使其工作。按下按钮什么也没做,因为 self.navigationController presentViewController.. 不会有任何效果,因为 self.navigationController 是 nil。 有趣!谢谢您的帮助。所以问题是调用 viewDidLoad 时模态视图的框架尚未更新。文档中是否明确定义了这种行为?我只是错过了吗?另外,我确实上传了带有错误的应用程序,我只是在测试该 navController 行但忘记将其取出。谢谢! 据我了解,在 viewDidLoad 中,该视图尚未添加到视图层次结构中,因此它还不知道其正确的框架,但在完成加载之后,它的时间大约出现/已经出现它知道真正的框架/边界信息。【参考方案2】:

这是 ios7 的新功能。如果在导航栏中嵌入UIViewController,它不会变小,因为默认导航栏是半透明的。

如果你改变视图控制器的背景颜色,你会看到它的顶部实际上是在导航栏的后面。

要在导航栏下方布置v1 视图控制器,您可以使用以下代码:

if ([v1 respondsToSelector:@selector(edgesForExtendedLayout)]) 
    v1.edgesForExtendedLayout = UIRectEdgeNone;

它的行为就像在 iOS6 中一样。

【讨论】:

这只会说明导航栏占据的 VC 高度有 44 个点的差异,而不是 VC 认为它们与呈现的 VC 大小相同的界限。【参考方案3】:

当从子视图控制器模态显示视图控制器时(一个比全屏显示的视图控制器是另一个视图控制器的子视图),这样做很重要,以便模态控制器知道画布的大小它出现在

childViewController.definesPresentationContext = YES; 
modalViewControllerWhichIsAboutToBePushed.modalPresentationStyle = UIModalPresentationCurrentContext

【讨论】:

以上是关于为啥我的模态呈现(表单)navController 的 rootViewController 在模态呈现时不知道它的尺寸较小?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的 Nativescript-vue 应用程序在呈现模态之前使用硬件后退按钮时崩溃?

为啥一个简单的模态视图控制器在呈现和关闭时会滞后?

在已经呈现的表单上呈现模态视图

为啥在呈现这个模态视图时会有延迟?

为啥我的应用程序崩溃调用“setupActionBarWithNavController(navController,appBarConfiguration)”

使用模态视图作为“正常”视图