【发布时间】:2014-11-06 02:40:43
【问题描述】:
我正在尝试创建一个像这样工作的可折叠工具栏(在 iOS 7 中运行——用于可视化目的的丑陋颜色等):
但是,当我在 iOS 8 中运行代码时,会发生以下情况: 我已经建立了一个基于以下内容的约束系统:
centering view(未显示)将工具栏保持在屏幕中间。
sizing view 被调整为折叠工具栏。 sizing view 锚定在 centering view 的右侧(通过 trailing 约束)。
container view 保存工具栏的实际内容。它锚定在sizing view 的右侧(也通过trailing 约束)。
各种content views 包含在container view 中。他们没有任何限制。系统默认应用的约束应该是宽、高、顶、左,这样可以保证它们在container view中保持相对位置。
工具栏的折叠实现如下:
- (IBAction)showLess:(id)sender {
self.widthConstraint.constant = 50; // adjust this number for collapse / expand
[UIView animateWithDuration:0.3 animations:^{
[self.centeringView layoutIfNeeded]; // trigger animation
}];
}
调整sizing view的宽度。
问题: iOS 8 似乎表现得好像我已经锚定了内容视图,但事实并非如此。
衷心感谢:
- 解释为什么 iOS 8 会对给定的(相当简单的)约束做出如此完全不同的解释。
- 关于如何在 iOS 8 中获得预期行为的指针
Source code 可用 here(适用于 iOS 8 的更新版本)。
更新:
Stack-overflow 的答案解决了这个问题。基本上,正确的答案是this,但它在this answer 中得到了很好的总结。
iOS7 和 iOS8 之间的区别不在于解释约束的方式,而在于更新命令通过视图层次结构向下传播的方式。
当我在 iOS 7 中首次实现该行为时,我注意到只有在 sizing view 的父视图(即 centering view)上调用 layoutIfNeeded 时,动画才能正常工作。在 iOS 7 中,这显然会自动降低视图层次结构。在 iOS 8 中,情况并非如此。您必须手动使约束已更改为setNeedsLayout 的视图无效,然后使用layoutIfNeeded 更新布局。我在更新代码中的解决方案如下所示:
- (IBAction)showLess:(id)sender {
self.widthConstraint.constant = 50;
[self.sizingView setNeedsLayout]; // *** THIS LINE IS NECESSARY TO MAKE THINGS WORK IN iOS 8
[UIView animateWithDuration:0.3 animations:^{
[self.sizingView layoutIfNeeded]; // trigger animation
}];
}
我希望这可以帮助其他也被这个前向兼容性问题困扰的人。
【问题讨论】:
-
我在我的一个应用中也看到了同样的情况。
-
给这个问题添加一个正常的答案,并标记为答案。我来这里两次以为它没有修复,然后我阅读了更新。
-
另外,考虑接受解决方案。
标签: ios autolayout constraints