简体   繁体   English

iOS8的Autolayout问题,代码在iOS7上运行良好

[英]Autolayout problems with iOS8 with code that works fine on iOS7

I'm in the midst of developing an app for the iPhone and iPad. 我正在为iPhone和iPad开发应用程序。 It supports iOS6 and iOS7 and it uses auto layout exclusively. 它支持iOS6和iOS7,并且它仅使用自动布局。

This past week, when Apple announced that iOS8 was ready for prime-time, I upgraded one of my iPhones and an iPad both to iOS8. 上周,当Apple宣布iOS8已经准备好迎接黄金时段时,我将其中一部iPhone和iPad升级到了iOS8。 I also bumped my XCODE up to version 6. I have 2nd iPhone which I left at iOS7. 我还将我的XCODE提升到版本6.我有第二部iPhone,我在iOS7上留下了。

I generated new executables with Xcode 6 and I was distressed to see that their screen layouts were messed up when executed on my devices running iOS8 but still fine on iOS7. 我用Xcode 6生成了新的可执行文件,当我在运行iOS8的设备上执行时,我看到他们的屏幕布局搞砸了,但在iOS7上仍然很好。 This is true on both my physical devices and on Xcode's emulators. 在我的物理设备和Xcode的仿真器上都是如此。

It took a lot of digging but I'm pretty clear now on what's happening though I don't know why. 虽然我不知道为什么,但我现在已经很清楚了解发生了什么。

Specifically, certain auto layout operations are failing for me on iOS8 but they are fine on iOS7. 具体来说,iOS8上的某些自动布局操作失败了,但在iOS7上它们没问题。

Some examples involving a button which I am placing on an underlying view whose size is equal to the size of the screen: 一些涉及按钮的示例,我将其放置在基本视图上,其大小等于屏幕大小:

(1) If I ask auto layout to position the button's horizontal center (CX) equal to the underlying view's horizontal center, the result is that the button's horizontal center is placed on the underlying view's left edge. (1)如果我要求自动布局将按钮的水平中心(CX)定位为等于基础视图的水平中心,则结果是按钮的水平中心位于基础视图的左边缘。

(2) If I ask auto layout to to make the width of the button equal to 50% of the width of the underlying view, it gives it no width at all. (2)如果我要求自动布局使按钮的宽度等于底层视图宽度的50%,则它根本没有宽度。

I am able to work around these issues as follows: 我能够解决这些问题如下:

(1) I ask auto layout to position the button's center equal to the underlying view's left edge plus 50% of the screen's width. (1)我要求自动布局将按钮的中心定位为等于底层视图的左边缘加上屏幕宽度的50%。

(2) I ask auto layout to make the button's width equal to 50% of the screen's width. (2)我要求自动布局使按钮的宽度等于屏幕宽度的50%。

I am slowly clawing my way, with workarounds like these, back to auto layout code that works for me on both iOS7 and iOS8. 我正在慢慢地抓住我的方式,使用类似这样的解决方法,回到在iOS7和iOS8上适用于我的自动布局代码。 But I am really wondering what's going on here. 但我真的很想知道这里发生了什么。

It looks like auto layout cannot determine the size of the underlying view and so auto layout calculations that require that information fail. 看起来自动布局无法确定基础视图的大小,因此需要信息失败的自动布局计算。 But it does know where the top and left edges of the view are so calculations based on those data succeed. 但它确实知道视图的顶部和左侧边缘在哪里,因此基于这些数据的计算成功。

This is a large app and I've written many hundreds of lines of auto layout code for iOS6 and iOS7 that work perfectly for me. 这是一个大型应用程序,我已经为iOS6和iOS7编写了数百行自动布局代码,对我来说非常适合。

I've been tweaking and trying things now with iOS8 for three days and I'm no wiser than I was when I began. 我一直在调试并尝试使用iOS8三天,而且我开始时并不比我更聪明。

Anyone have any suggestions or thoughts as to what might be the issue here? 任何人对这里的问题有什么建议或想法?

@robmayoff has a great answer for this: https://stackoverflow.com/a/26066992/1424669 @robmayoff对此有一个很好的答案: https ://stackoverflow.com/a/26066992/1424669

Essentially, in iOS8 you can no longer call setNeedsUpdateConstraints and setNeedsLayout on a view and expect the constraints of subviews to update. 基本上,在iOS8中,您不能再在视图上调用setNeedsUpdateConstraintssetNeedsLayout ,并期望更新子视图的约束。

You must call these methods on the view whose constraint is changing. 您必须在约束正在更改的视图上调用这些方法。 This is backwards compatible to iOS7. 这与iOS7向后兼容。

EXAMPLE: 例:

Suppose you have a ViewController with root view self.view and a subview called containerView. 假设您有一个带有根视图self.view的ViewController和一个名为containerView的子视图。 containerView has a NSLayoutConstraint attached to it that you want to change (in this case, top space). containerView附加了一个要更改的NSLayoutConstraint (在本例中为顶部空间)。

In iOS7 you could update all constraints in a VC by requesting a new layout for the root view: 在iOS7中,您可以通过为根视图请求新布局来更新VC中的所有约束:

self.containerView_TopSpace.constant = 0;
[self.view setNeedsUpdateConstraints];
[self.view setNeedsLayout];

In iOS8 you need to request layouts on the containerView: 在iOS8中,您需要在containerView上请求布局:

self.containerView_TopSpace.constant = 0;
[self.containerView setNeedsUpdateConstraints];
[self.containerView setNeedsLayout];

You might find the answers to this question helpful: UICollectionView cell subviews do not resize 您可能会发现此问题的答案有用: UICollectionView单元子视图不会调整大小

In most cases the works in iOS7 but not on iOS 8 auto layout problems seem to stem from the root view not being sized correctly in iOS 8, particularly when we set translatesAutoresizingMaskIntoConstraints to NO. 在大多数情况下,iOS7中的工作而不是iOS 8自动布局问题似乎源于iOS 8中根本视图的大小不正确,特别是当我们将translateAutoresizingMaskIntoConstraints设置为NO时。 For my views I was able to set the root view's frame in layoutSubviews (or whichever appropriate initializer that does have the correct bounds) and this resolved the issue. 对于我的观点,我能够在layoutSubviews中设置根视图的框架(或者具有正确边界的任何适当的初始化程序),这解决了这个问题。

self.contentView.frame = CGRectInset(self.bounds, 0, 0);

As shown in the answer above, you could also do 如上面的答案所示,你也可以这样做

self.contentView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;

and then turn translatesAutoresizingMaskIntoConstraints back to NO before you start setting your own constraints in code. 然后在开始在代码中设置自己的约束之前将translatesAutoresizingMaskIntoConstraints转回NO。

Definitely hate that so much of our time is taken with these annoying gotchas. 绝对讨厌我们花了很多时间来处理这些讨厌的陷阱。

In my case, the problem related to constraints labeled UIView-Encapsulated-Layout-Width and UIView-Encapsulated-Layout-Height . 在我的例子中,问题与标记为UIView-Encapsulated-Layout-WidthUIView-Encapsulated-Layout-Height约束有关。 When I removed them, everything behaved as though my view was of zero size, with everything centered on the upper left corner of the screen. 当我删除它们时,一切都表现得好像我的视图是零大小,一切都集中在屏幕的左上角。 When I left them in, new constraints worked as expected. 当我离开时,新的约束按预期工作。 I also retained the constraints labeled _UILayoutSupportConstraint . 我还保留了标记为_UILayoutSupportConstraint的约束。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在iOS7中递归-(void)layoutSubviews,但在iOS8中效果很好 - Recursion in - (void)layoutSubviews in iOS7 But works fine in iOS8 iOS8视图很好,但在iOS7上较小 - iOS8 view is fine but is smaller on iOS7 应用程序轮换在iOS7中有效,但在iOS8中无效 - App rotation works in iOS7 but not iOS8 UIScrollview在iOS8中工作,而不在iOS7中工作 - UIScrollview works in iOS8, not in iOS7 高度的自动版式可在iOS8中使用,但不能在iOS7中使用 - Autolayout for Height working in iOS8 but not working in iOS7 AutoLayout约束导入和拖尾在iOS7和iOS8上的行为不同 - AutoLayout constraints leadin & tailing acts different on iOS7 & iOS8 在iOS7和iOS8中,在自动布局下转换UILabel有所不同 - Transform UILabel under autolayout different in iOS7 and iOS8 iOS7上的UICollectionViewCell中的UIImageView自动布局问题,但在iOS8上也没关系 - UIImageView autolayout issue in UICollectionViewCell on iOS7 but on iOS8 it's ok 在iOS7中的iOS8中的QuickLook / QLPreviewController(QLPreviewItem)更改标题工作正常 - QuickLook/QLPreviewController(QLPreviewItem) change title in iOS8 in iOS7 works fine iOS7上的iOS宽高比约束中断,适用于iOS8 - iOS aspect ratio constraint breaks on iOS7, works on iOS8
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM