presentModalViewController如何与嵌套的UITabBarController和UINavigationController进行交互

时间:2009-11-05 19:15:23

标签: iphone objective-c cocoa-touch

我有一个视图,我想占用全屏,所以我重写了init方法,以及一些视图方法:

- (id) init {
  if (self = [super init]) {
    self.wantsFullScreenLayout = YES;
  }
  return self;
}
- (void) viewWillAppear:(BOOL)animated {
  [super viewWillAppear:animated];
  [[UIApplication sharedApplication] setStatusBarHidden:YES animated:YES];
}
- (void) viewWillDisappear:(BOOL)animated {
  [super viewWillDisappear:animated];
  [[UIApplication sharedApplication] setStatusBarHidden:NO animated:YES];
}

现在,从另一个屏幕,我想将其显示为模态视图:

UIViewController *screen = [[MyScreen alloc] init];
[self presentModalViewController:screen];
[screen release];

所有相当标准的东西。但是,当我希望全屏视图消失时,前一个视图会移动或拉伸大约40个像素。

具体来说,我的UITabBarController内部有UINavigationController,显示UITableViewController,这是显示子视图的视图,也是显示向上移动的视图。如果表不在导航控制器中,一切正常,根本没有任何东西向上移动。如果我尝试注释掉没有导航栏的wantsFullScreenLayout和setStatusBarHidden行,它有时会向上移动20个像素,或者实际上并不显示在整个屏幕上(但后来它不会更改任何代码),或者有时不会完全打破(但我没有得到任何这些完整的全屏)

我做错了什么?

3 个答案:

答案 0 :(得分:2)

通过Sean的建议和跳跃响应者链的某种组合,我发现一个有效的解决方案就像所有情况一样(到目前为止)。

第一期: 表格视图本身不会显示在导航控制器中,但如果从选项卡栏中的更多视图中选择,则可能会显示在一个中,并且在全屏幕中显示模态视图会导致表格不足导航回来后吧。

第二期: 当未在导航控制器中显示时,呈现模态视图不会占据整个屏幕(即使wantsFullScreenLayout设置为YES)。从此视图返回时,视图向上移动20个像素,您可以看到表格底部与标签栏顶部之间的间隙。

解决方案:

- (void) viewWillAppear:(BOOL)animated {
  [super viewWillAppear:animated];
  [self.navigationController setNavigationBarHidden:YES animated:NO];
  [self.navigationController setNavigationBarHidden:NO animated:NO];
}

- (void) presentModalViewController:(UIViewController *)screen animated:(BOOL)animated {
  UIResponder *responder = self;
  while (responder && ![responder isKindOfClass:[UITabBarController class]]) {
    responder = [responder nextResponder];
  }
  [(UIViewController *)responder presentModalViewController:screen animated:YES];
}

导航栏可见性的切换会强制重新布局。覆盖presentModalViewController实际上会调用tab键控制器上的presentModalViewController,然后使其显示在全屏幕上。出于某种原因,self.tabBarController在不在更多视图控制器中时为零,因此我必须跳起响应者链才能找到它。

答案 1 :(得分:1)

在解除模态视图之前,将使用viewWillAppear调用您的UINavigationController。您是否尝试在模式解除后可以看到的控制器内调用[[UIApplication sharedApplication] setStatusBarHidden:NO animated:NO];。当边界发生变化时,我遇到了大量在UINavigationControllers上显示模态视图的问题。它可以对抗任何布局变化,并且需要大量重置以前的状态才能使其表现良好。 <{1}}同样强制布局也可能没什么坏处。

如果效果很好,它可能会让你创建一个简单的基类,在它的viewWillAppear中设置这些基类,然后只为所有非模态视图控制器创建子类。

如果这不起作用,您可以尝试在包含标签栏控制器的顶层放置交换视图,然后在显示模态视图时可以通过转换删除标签栏控制器。是的,这不是技术上的模态,但仍然看起来不错,并提供相同的效果。那时候,由于视图控制器不在视图层次结构中,所以它不应该让它的布局全部用完。

答案 2 :(得分:0)

我认为这与presentModalViewController:调用的时间有关。作为测试,您可以在调用该方法之前尝试添加sleep(3)。如果它修复了任何东西,或者即使它没有,我猜我会尝试移动周围的事情。也许viewDidDisappear和viewDidAppear而不是'Wil​​l'