自动布局问题:iOS 7 vs iOS8

我正在尝试创build一个像这样工作的可折叠工具栏(在iOS 7中运行 – 用于可视化目的的丑陋颜色等):

iOS 7中的工具栏行为

但是,当我在iOS 8中运行代码时,会发生以下情况: 在这里输入图像说明 我已经build立了一个基于以下的约束系统: 可折叠的工具栏图

centering view (未示出)将工具栏保持在屏幕中间。 sizing view以折叠工具栏。 sizing view锚定在对中centering view的右侧(通过trailing约束)。 container view保存工具栏的实际内容。 它固定在sizing view的右侧(也通过trailing约束)。 容器content views中包含各种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中获得预期行为的指针

此处可用的源代码 (适用于iOS 8的更新版本)。

更新:这个问题已经解决堆栈溢出的答案。 基本上,这个答案是正确的,但是在这个答案中很好的总结了一下 。 iOS7和iOS8的区别并不在于解释约束的方式,而在于通过视图层次结构更新命令的方式。 当我在iOS 7中首先实现这个行为时,我注意到只有在sizing view的父sizing view (即centering view )上调用layoutIfNeeded ,animation才能正常工作。 在iOS 7中,这显然是自动涓stream的视图层次结构。 在iOS 8中,情况并非如此。 您必须手动使setNeedsLayout的约束更改的视图无效,然后使用layoutIfNeeded更新布局。 我更新的代码中的解决scheme如下所示:

 - (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 }]; } 

我希望这可以帮助那些也停留在这个向前兼容性问题上的人。

这个问题解决了堆栈溢出的答案。 基本上,这个答案是正确的,但是在这个答案中很好的总结了一下 。 iOS7和iOS8的区别并不在于解释约束的方式,而在于通过视图层次结构更新命令的方式。 当我在iOS 7中首先实现这个行为时,我注意到只有在sizing view的父sizing view (即centering view )上调用layoutIfNeeded ,animation才能正常工作。 在iOS 7中,这显然是自动涓stream的视图层次结构。 在iOS 8中,情况并非如此:您必须手动使用setNeedsLayout更改约束的视图,然后使用layoutIfNeeded更新布局。 我更新的代码中的解决scheme如下所示:

 - (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 }]; } 

我已经更新了问题以包含答案,但是为了回应@unmircea,我也发布了一个单独的答案。