旋转后 UINavigationController 中的 UITableView 在导航栏下

Posted

技术标签:

【中文标题】旋转后 UINavigationController 中的 UITableView 在导航栏下【英文标题】:UITableView in UINavigationController gets under Navigation Bar after rotation 【发布时间】:2009-12-10 16:14:55 【问题描述】:

这是肖像:

这是风景

我已经在轮换中尝试过,但没有成功:

self.tableView.autoresizesSubviews = YES;
self.tableView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;

【问题讨论】:

【参考方案1】:

我最近遇到了这个问题。就我而言,这是因为我正在执行不是应用程序窗口根控制器的导航控制器的旋转。因此,我使用旋转通知侦听器/仿射变换/边界调整方法来更改导航控制器的布局。这一切正常,但产生了这里描述的结果。我花了一段时间才注意到,当我旋转到横向时,导航栏的高度没有正确调整大小(即,从 44 像素到 32 像素,框架在横向模式下的高度降低了)。然而,我的应用程序的根视图控制器 响应了 willRotateToInterfaceOrientationdidRotateFromInterfaceOrientation。该视图控制器也已经知道关联的导航控制器。我通过将以下代码添加到 willRotateToInterfaceOrientation 方法来解决问题:

CGRect frame = self.navViewController.navigationBar.frame;
if (toInterfaceOrientation == UIInterfaceOrientationPortrait || toInterfaceOrientation == UIInterfaceOrientationPortraitUpsideDown) 
    frame.size.height = 44;
 else 
    frame.size.height = 32;

self.navViewController.navigationBar.frame = frame;

希望这可以为遇到类似情况的人节省一些时间。

【讨论】:

谢谢。不幸的是,在我的情况下,导航栏正在正确改变高度。似乎显示的视图在旋转时失去了导航栏的所有知识,因此它的顶部出现在导航栏下方。当另一个视图被推送然后弹出时,有问题的视图被正确地重新分配。我试过 setNeedsLayout,但没有用。 谢谢,完美运行。尽管您可以使用 (UIInterfaceOrientationIsPortrait(toInterfaceOrientation)) 代替您的 if 条件以使其更清洁。或者更好的是:frame.size.height = UIInterfaceOrientationIsPortrait(toInterfaceOrientation) ? 44. : 32.; 首先,这对我有用,这很烦人。其次,我发现将代码放在“willRotate”中比放在“didRotate”中效果更好(这似乎会导致视觉跳跃)。第三,我认为这发生在我的案例中,因为我的根控制器是一个标签栏,而单个标签有一个导航控制器。正如@jstevenco 所指出的,根控制器正在获取方向调用,而不是导航控制器。我想知道是否有更清洁的东西:根控制器告诉导航控制器布局其子视图的方法,好吗?【参考方案2】:

当使用自定义视图控制器作为根管理其他视图控制器时,它负责将所有旋转事件转发到当前活动的子控制器(如果我可以这样称呼它)。这些事件是:

– willRotateToInterfaceOrientation:duration:

– willAnimateRotationToInterfaceOrientation:duration:

– didRotateFromInterfaceOrientation:

– willAnimateFirstHalfOfRotationToInterfaceOrientation:duration:

– didAnimateFirstHalfOfRotationToInterfaceOrientation:

– willAnimateSecondHalfOfRotationFromInterfaceOrientation:duration:

因此,对于由您的自定义根控制器管理的导航控制器,将– willAnimateRotationToInterfaceOrientation:duration: 转发到导航控制器可以解决旋转时导航栏高度错误的问题。

【讨论】:

这是最干净的解决方案。 这应该是公认的答案。另外请注意,在 ios 5 和 6 中,您可以自动向前旋转和外观方法。【参考方案3】:

在 didRotateFromInterfaceOrientation 方法中添加以下行。

[self.navigationController.view layoutSubviews];

我希望这样做。

【讨论】:

【参考方案4】:

我有完全相同的问题,@jstevenco 引导我找到了一个非常奇怪的解决方案。 我的视图也会在旋转时自动调整大小,但 tableview 似乎不明白那里有一个导航控制器:

在 tableviewcontroller 中,添加以下内容:

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation

[super didRotateFromInterfaceOrientation:fromInterfaceOrientation];
 CGRect frame = navBar.frame;
if (fromInterfaceOrientation == UIInterfaceOrientationPortrait || fromInterfaceOrientation == UIInterfaceOrientationPortraitUpsideDown) 
    frame.size.height = 31.9;
 else 
    frame.size.height = 44.1;

navBar.frame = frame;  


奇怪的是31.9和44.1很重要!留下这些是 32 和 44,没有调整大小,所以它似乎忽略它。为我工作,希望对其他人有所帮助。

【讨论】:

【参考方案5】:

我看起来表格视图在方向更改后向下滚动了一点。

您是否尝试过调用scrollToRowAtIndexPath:atScrollPosition:animated: 并滚动到最顶行?

【讨论】:

不,不是那个原因,当您向下扫时,它又会出现在导航栏下方。在下方,还有一个工具栏具有相同的结果。横向模式下 tableView 的下半部分在其下方【参考方案6】:

如果您在导航控制器中调用了“willAnimateRotationToInterfaceOrientation:”,但忘记在方法中调用 super,则可能会出现此问题。

你应该有这样的东西:

        - (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration 
        [super willAnimateRotationToInterfaceOrientation:toInterfaceOrientation];
// Your code here

    

【讨论】:

如果我添加该代码,我会在编译时收到此警告:'UITableViewController' may not respond to '-willAnimateRotationToInterfaceOrientation:' 代码 sn-p 需要进入您的导航控制器,而不是您的 TVC。 如果我添加该代码,我会在编译时收到此警告:'UIViewController' may not respond to '-willAnimateRotationToInterfaceOrientation:' -Suchita 如果我把它放在我的 tableViewController 或我的 navigationController 中,我也会收到警告。【参考方案7】:

在这些情况下要注意的一件事是如果您手动更改状态栏的方向。如果状态栏未隐藏并且您在状态栏处于错误方向时更改了视图的框架(在您的代码中,您可能在框架更改后立即更新状态栏的方向),它将自动即使您没有启用自动调整大小,也会错误地调整导航栏的大小。

【讨论】:

【参考方案8】:

您的UINavigationController 需要在设备方向发生变化时得到通知。如果您只将UINavigationControllerview 添加到另一个UIView,则不会发生这种情况。

从 iOS 5 开始,您可以简单地在父级 UIViewController 上调用 addChildViewController:,这将确保将方向更改传播到此子视图控制器。

【讨论】:

以上是关于旋转后 UINavigationController 中的 UITableView 在导航栏下的主要内容,如果未能解决你的问题,请参考以下文章

手机重启后软件不能旋转了是啥原因?

旋转 UIView 并在旋转后保持纵横比

旋转更改后 UINavigationBar 消失

拉达旋转动画在 stop() 后保持旋转一秒钟

旋转后图像变质

当我们开始旋转设备并完成后会调用啥方法