UINavigationBar 旋转和自动布局
Posted
技术标签:
【中文标题】UINavigationBar 旋转和自动布局【英文标题】:UINavigationBar rotation and auto layout 【发布时间】:2013-10-24 20:37:42 【问题描述】:关于通过在场景中插入 UINavigationBar 来设计您自己的视图控制器,我发现很多关于在旋转设备时帧高度如何不改变的问题的参考。这与 Apple 在其导航控制器中利用 UINavigationBar 的方式形成鲜明对比,其中栏的高度在旋转时会发生变化。
虽然有一些建议确实显示了如何更改高度以与 Apple 所做的一致,但所有答案都没有解决与场景中其他视图的正确关系。特别是,在构建使用 autoLayout 的场景时,您永远不必调整框架 - 假设自动布局会通过您定义的约束为您解决这个问题。
例如,一个suggestion 就是这样做的:
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
[self.navigationBar performSelector:@selector(sizeToFit) withObject:nil afterDelay:(0.5f * duration)];
虽然这会改变大小,但与其他视图的关系不再正确。尽管上面示例中的海报确实提供了一种解决关系调整的解决方案,但这更像是一种硬编码方法,Apple 可能不会建议,即不是一个对自动布局友好的解决方案。
通过实验,我注意到在旋转设备时,intrinsicContentSize 实际上确实发生了正确的变化,但框架没有。注意到这一点,我尝试了以下方法:
- (void)viewDidLayoutSubviews
[super viewDidLayoutSubviews];
CGRect frame = self.navigationBar.frame;
frame.size.height = self.navigationBar.intrinsicContentSize.height;
self.navigationBar.frame = frame;
虽然这确实正确地改变了大小,就像上面的例子一样,但它也导致了不正确的视图关系。
具体来说,我的横向设备:
然后切换到纵向:
有人知道 Apple 希望我们如何使用约束来解决 UINavigationBar 布局问题吗?
【问题讨论】:
【参考方案1】:只需在按钮和顶部布局指南之间设置垂直间距限制。这可以在 IB 中通过控制从按钮拖动到导航栏底部来完成。很简单,不需要代码。
编辑后:如果您添加一个独立的导航栏,您确实需要一些代码(据我所知)来获得使用导航控制器自动获得的行为。我这样做的方法是添加一个导航栏,并将其约束到超级视图的两侧,对顶部布局指南进行垂直约束,以及 44 点的固定高度。我为此约束创建了一个 IBOutlet(在下面的代码中称为 heightCon)。该按钮对导航栏有 centerX 约束和垂直间距约束。
- (void)viewWillLayoutSubviews
self.heightCon.constant = (self.view.bounds.size.height > self.view.bounds.size.width)? 44 : 32;
【讨论】:
是的,这个建议对上面的例子有帮助。然而,代码是必要的,因为导航栏的高度需要调整——这确实是帖子的重点。此外,目标是在栏大小发生变化时保持按钮和栏之间的空间。 @zinc1oxide,看起来他在谈论你在旋转 iPhone 时自动获得的高度变化——不需要代码。 旋转时高度不会自动变化。在上述建议中,更改按钮约束不会影响导航栏在旋转时的高度。如果您知道通过定义约束来更改高度的方法,那将是理想的。 @zinc1oxide,我不知道你在看什么,但在我的手机和模拟器(7.0 版)上,导航栏纵向高 44 点,横向高 32 点——这是自动发生的,是 iPhone 上导航栏的正常行为。 @zinc1oxide,好的,我明白你现在在做什么。我已经更新了我的答案。以上是关于UINavigationBar 旋转和自动布局的主要内容,如果未能解决你的问题,请参考以下文章
旋转到横向时自动调整 UINavigationBar 的大小
使用 UINavigationBar 和 UIBarButtonItem 自动布局
自动布局 UITextField 以适应 UINavigationBar