在dismissModalViewControllerAnimated之后,父视图设置为全屏

时间:2010-09-17 13:05:21

标签: iphone cocoa-touch uikit

每次关闭ModalViewController后,父视图都会设置为全屏。为什么呢?

Before                After
+----------------+   +------------------+
|head            |   | detailview       |
+----------------+   |                  |
|detailview      |   |                  |
|                |   |                  |
|                |   |                  |
|                |   |                  |
+----------------+   +------------------+

我创建了一个出现错误的“简单”示例项目。

http://github.com/rphl/modalTest

请看一下。

4 个答案:

答案 0 :(得分:8)

这有点猜测,但是在稍微使用了你的代码后,这是一个有根据的猜测。

当您呈现模态视图时,它将添加为属于调用presentModalViewController的控制器的视图的子视图。由于模态视图旨在全屏显示,因此看起来好像内部超视图的框架是全屏显示的。

我在MyDetailViewController中添加了以下内容:

- (void)viewDidLoad {
    [super viewDidLoad];
    CGRect frame = self.navigationController.view.frame;
    NSLog(@"%@", NSStringFromCGRect(frame));
}

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    CGRect frame = self.navigationController.view.frame;
    NSLog(@"%@", NSStringFromCGRect(frame));
}

导致以下输出:

2010-09-19 00:23:51.823 ModalTest[2478:207] {{0, 164}, {320, 316}}
2010-09-19 00:23:56.178 ModalTest[2478:207] {{0, 0}, {320, 480}}

首次出现细节时输出第一行。当模态视图被解除时输出第二行。

现在我实际上并不特别喜欢我找到的解决方案,但这会产生预期的效果。在sendMail方法中:

ModalTestAppDelegate* appDelegate = [[UIApplication sharedApplication] delegate];
[appDelegate.viewController presentModalViewController:controller animated:YES];

并使用mailComposeController:didFinishWithResulterror:方法:

ModalTestAppDelegate* appDelegate = [[UIApplication sharedApplication] delegate];
[appDelegate.viewController dismissModalViewControllerAnimated:YES];

基本上这可以确保它是持有应用程序主UI的全屏视图,呈现全屏模式视图。我不认为这是理想的,因为我并不是代码的深层部分能够像这样深入到应用代理中。

答案 1 :(得分:5)

对我有用的东西是在解除模态视图控制器后恢复帧。代码示例:

呈现模态视图控制器

[self presentModalViewController:self.modalViewController animated:YES];

解雇模态视图控制器

CGRect frame = self.view.frame;
[self.modalViewController dismissModalViewControllerAnimated:YES];
self.view.frame = frame;

答案 2 :(得分:2)

我为iPad准备了iPhone应用后遇到了这个问题。事实证明这是非常奇怪的事情,我花了几个小时才找到它。这与自转有关。

有关:

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {

我回来了否

以前我回来了:

    return (interfaceOrientation == UIInterfaceOrientationPortrait);

出于某种原因,在取消模态视图控制器后,返回No导致导航栏位于状态栏下方。

答案 3 :(得分:1)

这个问题很久以前就被问过了,但我想通过分享我的经验来帮助别人,因为我需要一段时间才能弄明白。

我有一个控制器,它被推入导航控制器,它本身就是UITabBarController中的第一个标签。从我的控制器中,我提出了一个模态视图控制器,它使用MPMoviePlayerController播放全屏视频。当视频结束时,我以编程方式关闭模态视图控制器并返回上一屏幕。但有时在解雇后状态栏消失,导航栏被调整大小以占据状态栏的空间。其他时候,导航栏被剪掉了一半,看起来好像它是状态栏的下方。

在大多数情况下都注意到了这种行为,但并非总是如此,这使得它非常混乱。我在StackOverflow上尝试了很多其他人的建议,其中明确隐藏了viewWillAppear:中的状态栏,在YES中至少返回一个方向shouldAutorotateToInterfaceOrientation:,呈现模态从导航控制器或甚至tabBar控制器(我的窗口的根视图控制器)查看控制器,从协议方法中解除,而不是直接从模态视图控制器调用dismissViewControllerAnimated:completion:,使用MPMoviePlayerController通知和状态。似乎没有任何帮助。

最后,我意识到我的问题只发生在视频结束并且视频控件(包括状态栏)被隐藏时。我想这是因为我的模态视图控制器是全屏的(将wantsFullScreenLayout属性设置为YES)并且从导航控制器内的视图控制器和tabBar控制器中显示,当状态栏隐藏在在解雇的那一刻,这会强制导航控制器调整其子视图控制器的大小并填充屏幕,隐藏状态栏或重叠它。我实际上能够通过记录我的DetailsViewController(在导航控制器内部推送的那个)的大小来看到这一点。

所以,我做了最直观的事情 - 我在解雇模态视图控制器之前明确地显示了状态栏。这完全解决了它,现在我的代码看起来像这样:

<强> 1。从DetailsViewController

呈现模态视图控制器
[self presentViewController:controller animated:YES completion:NULL];  

<强> 2。从自身中解除模态视图控制器

[[UIApplication sharedApplication] setStatusBarHidden:NO];  
[self dismissViewControllerAnimated:YES completion:nil];