我正在尝试创建一个可折叠的工具栏,其操作方式如下(在运行iOS 7的设备上--为了可视化目的使用丑陋的颜色):
我已经建立了一个基于以下内容的约束系统:
一个
![enter image description here](https://istack.dev59.com/tkMU2.gif)
![collapsible toolbar diagram](https://istack.dev59.com/nrglr.webp)
居中视图
(未显示)将工具栏保持在屏幕中央。一个调整大小视图
被调整为折叠工具栏。调整大小视图
通过尾随
约束与居中视图
右侧连接。一个容器视图
包含工具栏的实际内容。它通过尾随
约束与调整大小视图
右侧连接。各种内容视图
包含在容器视图
中。它们没有约束。系统应用的默认约束应该是宽度、高度、顶部、左侧,这确保它们在容器视图
中保持相对位置。工具栏的折叠如下实现:- (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中获得预期的行为。
更新:
该问题已经通过Stack-overflow上的答案得到解决。基本上,正确的答案是this,但是这个答案在this answer中被很好地总结了。
iOS7和iOS8之间的区别不在于解释约束的方式,而在于更新命令如何通过视图层次结构进行传递。
当我首先在iOS 7中实现这个行为时,我注意到只有在调用layoutIfNeeded
时才能正常工作,即在centering view
上(即sizing 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
}];
}
我希望这能帮助其他遇到向前兼容问题的人。