我正在尝试创建一个可折叠的工具栏,其工作方式如下(在 iOS 7 中运行 - 出于可视化目的,颜色丑陋等):
However, when I run the code in iOS 8, this is what happens:
I have set up a constraint system that is based on the following:
A centering view
(未显示)将工具栏保持在屏幕中间。
Asizing view
调整为折叠工具栏。这sizing view
固定在右侧centering view
(via a trailing
约束)。
Acontainer 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
.
Problem:iOS 8 的表现就好像我已经锚定了内容视图,但事实并非如此。
我衷心感谢:
- 解释为什么 iOS 8 对给定的(相当简单的)约束有如此完全不同的解释。
- 关于如何在 iOS 8 中获得预期行为的指针
源代码 https://www.dropbox.com/s/4j7ut7mns5wm6bn/AutoLayoutIssueStackOverFlow.zip?dl=0可用的here https://www.dropbox.com/s/4j7ut7mns5wm6bn/AutoLayoutIssueStackOverFlow.zip?dl=0(适用于 iOS 8 的更新版本)。
UPDATE:Stack-overflow 的答案解决了这个问题。基本上,正确答案是this https://stackoverflow.com/a/26066992/228342,但它被很好地总结为这个答案 https://stackoverflow.com/a/26070049/228342。
iOS7 和 iOS8 之间的区别不在于约束的解释方式,而在于更新命令通过视图层次结构向下传递的方式。
当我首先在 iOS 7 中实现该行为时,我注意到动画只有在调用时才能正常工作layoutIfNeeded
在父视图上sizing view
(即在centering view
)。在 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
}];
}
我希望这可以帮助其他也陷入此向前兼容性问题的人。