自动布局视图在popViewController时导致应用程序崩溃

6

最终更新 - 已解决

我已经解决了这个问题。看起来在玩弄代码时(这是我第一次使用Swift和AutoLayout),我改变了一些视图的contentCompressionResistancePrioritycontentHuggingPriority。将该代码删除并将所有视图重置为IB中的默认值即可解决我的问题。

初始帖子

因此,我正在iOS上使用AutoLayout来定位我的动态视图。一切都很顺利,直到我退出其中一个视图控制器。应用程序崩溃,并显示一个非常不友好的错误消息,大致如下:

...
internal error.  Cannot find an outgoing row head for incoming head UIImageView:0xd049d50.Width{id: 730}, which should never happen.'
...

我一直在搜寻和搜索网络,但是无法解决问题。然而,我发现我的代码中有一行可以做出改变。在我的视图控制器中,我有一堆UIImageView使用了自动布局,并且这些图片从网上加载。

如果我将接收到的图片设置为空的([[UIImage alloc] init]UIImage())在Swift中,就不会再崩溃了。

我甚至尝试从应用程序包中设置虚拟图片,但那也导致了崩溃。

非常感谢您提供任何建议!

更新1

再次查看代码时,我发现与那些 UIImageViews 相关的约束也会使崩溃消失。它是一个纵横比约束,看起来像这样:

imageView.addConstraint(NSLayoutConstraint(item: imageView, attribute: NSLayoutAttribute.Width, relatedBy: NSLayoutRelation.Equal, toItem: imageView, attribute: NSLayoutAttribute.Height, multiplier: 8.0 / 5.0, constant: 0.0))

我是否做错了什么?我真的需要满足这个纵横比,所以我不能删除它。

更新2

我再试验一下,发现了一种方法使它工作。但我不满意它,因为它没有让我理解发生了什么,而且有点像黑客行为。

让我向您展示我的视图结构:

  • 视图
    • 滚动视图
      • 内容视图
        • 封面图片视图(来自IB)
        • 标题标签(来自IB)
        • ...更多的标签或图片视图按代码中的随机顺序...

这些视图的放置方式如下:

  • 封面图片视图与ContentView同宽,纵横比为8:5,顶部没有空间
  • 每个标签有10px的前导空间和10px的后续空间
  • 每个图片视图与ContentView同宽,纵横比为8:5
  • 所有视图之间都有10px的间隙,最后一个视图与ContentView之间有10px的底部间距

我的解决方法是在viewWillDisappear时从堆栈中删除ContentView,但这会使ViewController弹出时屏幕闪烁。

我检查了1000次我的约束创建代码,看起来没问题。如果您想看到它,请告诉我,我会在这里发布它。


1
这有用吗?https://dev59.com/0Oo6XIcBkEYKwwoYLhbh - DogCoffee
嗯...我之前确实读过它,但似乎没有什么帮助。不过这让我再次检查了我的代码,发现了另一件事情。我会在问题中更新它。 - Mihai Fratu
似乎你的 UIImageView.image 在后台被释放了。 - randomx
另一种方法是将约束拖到您的VC中,就像使用IBOutlet / Action一样-这样您可以通过代码根据需要更改它的方面。从错误中,您可能正在尝试使用一个约束设置宽度,然后使用另一个约束设置纵横比?结果,这两个约束会发生冲突? - DogCoffee
似乎确实存在某个约束问题,但我真的无法弄清楚发生了什么。我无法在IB中设置约束,因为这些视图是根据从服务器获取的数据以编程方式创建的。我已经设法只让它有时崩溃。我仍在努力解决它,如果我解决了它,我会发布我的解决方案。 - Mihai Fratu
5个回答

11

在这里加上一些内容,以防有人遇到动态代码生成的 aspectRatio 约束问题。我更改了纵横比约束中 HeightWidth 关系的顺序(与问题中的约束相比):

aspectConstraint = NSLayoutConstraint(item: cardMedia, attribute: NSLayoutAttribute.Height , relatedBy: NSLayoutRelation.Equal, toItem: cardMedia, attribute: NSLayoutAttribute.Width, multiplier: aspect, constant: 0.0)

乘数 aspect 的计算方法如下:

let aspect = image.size.height / image.size.width

这似乎可以防止崩溃发生。希望这对某人有所帮助。


3
可笑,但却奏效了。将接口构建中的宽高比约束从W:H = 16:9 改为 H:W = 9:16。 - sust86
1
很好。我这样做是因为在我的情况下,项目的宽度是固定的,只有高度在变化。我遵循了这个公式 item1.attribute1 = multiplier × item2.attribute2 + constant - Mickey Mouse

3
似乎原帖作者的问题已经解决了,但我遇到了一个类似的问题,并找到了不同的解决方案。在这里发帖,以防其他人遇到我的问题并找到这篇文章。
我的应用在iPhone 5s上的iOS 7模拟器中崩溃了,但在iOS 8或其他设备上没有出现问题。当我的控制器被弹出时,我也会遇到相同的错误(“找不到传入头的输出行头...”),以及当在UIPageViewController中滚动控制器时也会出现相同的错误。
在两种情况下,问题都是由于我使用诸如UIView.insertSubview:belowSubview:和UIView.bringSubviewToFront:之类的API将全屏视图堆叠在一起触发的。解决方案/解决方法是更改我们的代码,以动态添加/删除我们的视图,而不是堆叠它们并改变它们的顺序。
希望这可以帮助任何遇到相同问题的人。

2

好的,我已经修复了它。看起来我的一些约束条件设置不正确。休息喝咖啡后,我找出了哪些是不正确的,现在这个东西就不会再崩溃了。


1
你让我朝着正确的方向前进。我移除了一些对于一个正在被关闭的视图存在的纵横比约束,这个问题就解决了。我不确定为什么这会导致崩溃,并且它也不是每次都发生。 - McFadden

0
在我的情况下,这是因为我试图使用自动布局来布置一个视图的子视图,而该视图的高度为CGFLOAT_MAX。 同样的代码在iOS7上运行良好,但在iOS6上崩溃。

0

我自己也遇到了非常相似的崩溃。有趣的是,它也与 UIImageView 有关。在我的情况下,通过改变(或删除)调整此图像视图的内容压缩阻力内容吸附优先级的代码执行顺序来缓解了问题。

在这里查看我的答案的更多细节:https://dev59.com/0Oo6XIcBkEYKwwoYLhbh#27284071

根据您的情况,似乎您的“纵横比”约束触发了类似的问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接