【发布时间】:2014-05-21 17:42:43
【问题描述】:
我有一个简单的布局,其中有一个 UINavigationViewController 和一个显示在其中的常规视图控制器。然后我有一个固定大小的图像,以及一些应该填充剩余空间的文本。见下文:
前景中图像的顶部受限于顶部布局指南,这在 Xcode 中运行良好(不显示任何警告或任何内容),但在运行时似乎被忽略了:
图像的顶部锚定在屏幕顶部,而不是导航栏的底部。我知道这不一定不正确(表格视图在导航栏下方向上滚动),但这非常烦人,因为这里不涉及滚动。
但是等等,还有更多。如果我旋转屏幕,它会自行修复!
我尝试了诸如在不同的地方添加对layoutIfNeeded 的呼叫之类的方法,但无济于事。
我做错了什么?
旁注:
- 我在设备上进行了测试,它的行为完全相同,所以我只截取了模拟器
- 忽略背景图像视图,它不相关
- 我不知道为什么文本显示在 Xcode 中被截断,但它似乎在运行时工作正常,所以我不在乎
根据下面 dasdom 的评论,我尝试在代码中添加此约束,但没有明显变化。不过,我不能 100% 确定我做对了:
-(void)viewDidLayoutSubviews {
NSMutableDictionary * views = [NSMutableDictionary new];
views[@"v"] = self.imageView;
views[@"topLayoutGuide"] = self.topLayoutGuide;
NSMutableArray * constraints = [NSMutableArray new];
[constraints addObjectsFromArray:[NSLayoutConstraint
constraintsWithVisualFormat:@"V:[topLayoutGuide][v]"
options:0
metrics:nil
views:views]
];
[self.view addConstraints:constraints];
[self.view layoutSubviews];
}
一些调试输出:
如果我在viewWillAppear 期间打印出导航控制器,我会得到:
2014-05-21 14:45:51.961 iBeaconMap[914:60b] self.navigationController.navigationBar: <UINavigationBar: 0x8cbded0; frame = (0 20; 320 44); opaque = NO; autoresize = W; userInteractionEnabled = NO; gestureRecognizers = <NSArray: 0x8c72440>; layer = <CALayer: 0x8cbe010>>
如果我设置一个计时器以定期打印出topLayoutGuide 的值,它会显示“20”直到我第一次旋转,此时它会根据方向显示“52”或“64”(如预期)。
也许我需要弄清楚旋转对导航控制器做了什么,并模拟它....... 正在抓住稻草
【问题讨论】:
-
类似的东西让我相信 Interface Builder 还不足以做自动布局。尝试将约束添加到视图控制器中
viewWillAppear:的顶部布局指南中。 -
我刚刚尝试过,但它似乎没有改变任何东西。我已经用我使用的代码更新了这个问题。我在
viewDidLayoutSubviews中实现了它,因为这似乎是苹果推荐的。不过,没有骰子。 -
导航栏已经存在了吗?尝试在调试器中打印出顶部布局指南。
-
我不确定它是否“存在”,但
self.topLayoutGuide.length打印出20(大概是状态栏)。如果我发疯并要求self.navigationController.topLayoutGuide.length,它会返回0。这可能解释了我的本地 topLayoutGuide 不正确,尽管它没有解释为什么...... -
帮我一个忙,并将其添加到 viewWillAppear 中进行测试。并添加以下日志:
NSLog(@"self.navigationController.navigationBar: %@", self.navigationController.navigationBar);
标签: ios cocoa-touch autolayout interface-builder