自动布局问题:iOS 7和iOS8 [英] Auto-Layout Issues: iOS 7 vs iOS8

查看:185
本文介绍了自动布局问题:iOS 7和iOS8的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图创建一个可折叠的工具栏,工作原理像这样(运行在iOS 7 - 丑陋的颜色等可视化的目的):

I am trying to create a collapsible toolbar that works like this (running in iOS 7 -- ugly colors etc. for visualization purposes):

但是,当我运行代码iOS 8,这是发生了什么:

我设置了一个基于以下内容的约束系统:

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 居中视图(未显示)将工具栏保持在屏幕中间。
A 调整视图已调整为折叠工具栏。 大小视图锚定在中心视图右侧(通过尾随 constraint)。
容器视图保存工具栏的实际内容。它锚定在大小视图(也通过尾随约束)的右侧。
各种内容视图包含在容器视图中。他们没有约束。系统应用的默认约束应该是width,height,top,left,这将确保它们在容器视图中保持其相对位置。

A centering view (not shown) keeps the toolbar in the screen middle. A sizing view is adjusted to collapse the toolbar. The sizing view is anchored to the right of the centering view(via a trailing constraint). A container view holds the actual content of the toolbar. It is anchored to the right of the sizing view (also via a trailing constraint). Various content views are contained in the container view. They have no constraints. The default constraints applied by the system should be width, height, top, left, which ensures that they keep their relative positions in the 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
    }];
}

这会调整 code>。

Which adjusts the width of the sizing view.

问题:
iOS 8的行为似乎是我离开了内容视图,

Problem: iOS 8 seems to behave as if I had left anchored the content view, but this is not true.

我真诚地感谢:


  • 为什么iOS 8会对给定的(相当简单的)约束有如此完全不同的解释。

  • 一个指针,告诉我如何在iOS 8中获得预期的行为

源代码可用此处(更新版本,在iOS 8中工作)。

Source code available here (updated version that works in iOS 8).

UPDATE:
这个问题已经解决了Stack-overflow的问题。基本上,正确的答案是,但它在此回答
iOS7和iOS8之间的区别不是解释约束,而是更新命令通过视图层次结构向下延伸的方式。
当我在iOS 7中首先实现该行为时,我注意到动画只能在<$ c $的父视图上调用 layoutIfNeeded c>调整视图
(即在中心视图)。在iOS 7中,这显然是自动地向下浏览视图层次。在iOS 8中,情况并非如此。您必须手动使用 setNeedsLayout 更改约束的视图失效,然后使用 layoutIfNeeded 更新布局。我的更新代码解决方案如下:

UPDATE: The issue was solved with answers from Stack-overflow. Basically, the right answer is this, but it was nicely summarized in this answer. The difference between iOS7 and iOS8 is not in the way the constraints are interpreted, but in the way that update commands are trickled down through the view hierarchy. When I implemented the behavior first in iOS 7, I noticed that the animation would only work properly if I called layoutIfNeeded on the parent view of the sizing view (i.e. on centering view). In iOS 7 this apparently trickled down the view hierarchy automatically. In iOS 8, this is not the case. You have to manually invalidate the view whose constraints have changed with setNeedsLayout, and then update the layout with layoutIfNeeded. My solution in the updated code looks like this:

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

我希望这可以帮助那些也困扰这种向前兼容性问题的人。 / p>

I hope this helps others who are also stuck on this forward compatibility issue.

推荐答案

问题解决了从堆栈溢出的答案。基本上,正确的答案是,但它在此回答。 iOS7和iOS8之间的区别不是限制解释的方式,而是在更新命令通过视图层次结构下降的方式。当我在iOS 7中首先实现该行为时,我注意到,如果在大小视图的父视图中调用 layoutIfNeeded (即在中心视图)。在iOS 7中,这显然是自动地向下浏览视图层次。在iOS 8中,这是的情况:您必须手动无效的视图,其约束已更改与 setNeedsLayout ,然后更新布局与 layoutIfNeeded 。我的更新代码解决方案如下:

The issue was solved with answers from Stack-overflow. Basically, the right answer is this, but it was nicely summarized in this answer. The difference between iOS7 and iOS8 is not in the way the constraints are interpreted, but in the way that update commands are trickled down through the view hierarchy. When I implemented the behavior first in iOS 7, I noticed that the animation would only work properly if I called layoutIfNeeded on the parent view of the sizing view (i.e. on centering view). In iOS 7 this apparently trickled down the view hierarchy automatically. In iOS 8, this is not the case: You have to manually invalidate the view whose constraints have changed with setNeedsLayout, and then update the layout with layoutIfNeeded. My solution in the updated code looks like this:

- (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我也张贴一个单独的答案,以及。

I've updated the question to include the answer, but in response to @unmircea I am posting a separate answer, as well.

这篇关于自动布局问题:iOS 7和iOS8的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆