Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AutoLayout views make app crash on popViewController

Final Update - Fixed

I have fixed this. It seems that while playing around (this is my first project in Swift and using AutoLayout) I have changed the contentCompressionResistancePriority and contentHuggingPriority for some of my views. Taking that code out and reseting all my views to default values in IB fixed my problem.

Initial Post

So I am using AutoLayout on iOS to position my dynamic views. It's all working nice and easy until I pop one of my view controllers. The app crashes with a really not helpful error message that goes something like this:

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

I've been pocking around and searched the web but I cannot fix it. I've discovered though that there is one line in my code that can make a difference. In my said view controller I have a bunch of UIImageViews that are using AutoLayout and who's images I load from the web.

If instead of setting my received image to them I set an empty one ([[UIImage alloc] init] or UIImage()) in Swift as is my case exactly) it doesn't crash anymore.

I even tried setting a dummy image from the app bundle but that makes it crash too.

Any suggestions would be much appreciated!

Update 1

Looking trough the code once more I also found out that there is a constraint related to those UIImageViews that also makes the crash to go away when eliminated. It's an aspect ratio constraint and it looks like this

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

Am I doing something wrong? I really need this aspect ratio to be satisfied so I can't really remove it

Update 2

Messing a little bit more with it I've figured a way to make it work. But I'm not happy with it 'cause it didn't made me understand what's going on and it's kind of a hack

Let me layout my view structure to you:

  • View
    • Scroll View
      • ContentView
        • Cover ImageView (from IB)
        • Title Label (from IB)
        • ... more Labels or ImageViews in random order from code ...

The way these views are placed is like this:

  • The Cover ImageView is as wide as the ContentView and has an aspect ratio of 8:5 with no space on top
  • Each Label has a 10px leading space and a 10px trailing space
  • Each ImageView is as wide as the ContentView and has an aspect ratio of 8:5
  • All views have a 10px gap beewtwen them and the last one has 10px bottom spacing to the ContentView

My fix to my crash was to remove ContentView from the stack on viewWillDisappear but that makes the screen flash when the ViewController is popped.

I've checked my constraints creating code a 1000 times and it seems right. If you want to see it let me know and I'll post it over here

like image 965
Mihai Fratu Avatar asked Jun 13 '14 23:06

Mihai Fratu


3 Answers

Just putting this here in case anyone has the same issue with a dynamic, code-generated aspectRatio constraint. I switched the order of the Height and Width relationship in the aspect-ratio constraint (compare to the one in the question):

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

Where the multiplier aspect is calculated by:

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

And that seems to stop the crash from happening. Hope this helps someone.

like image 186
Mickey Mouse Avatar answered Sep 22 '22 10:09

Mickey Mouse


It sounds like the original poster's problem is solved, but I just ran across a similar problem with a different solution. Posting it here in case anyone else runs into my issue and finds this post.

My app was crashing in iOS 7 on the iPhone 5s (in the simulator), but not on iOS 8 or on other devices. I was getting this same error ("Cannot find an outgoing row head for incoming head ...") when my controllers were being popped... and also when controllers were being scrolled away from in a UIPageViewController.

In both cases, the problem was triggered by the fact that I had full-screen views stacked on top of each other using APIs like UIView.insertSubview:belowSubview: and UIView.bringSubviewToFront: . The solution/workaround was to change our code to dynamically add/remove our views instead of stacking them and shuffling their order.

Hope this helps anyone else who hits the same problem.

like image 41
Ghazgkull Avatar answered Sep 21 '22 10:09

Ghazgkull


Ok. I've fixed it. It seems that I had somme of my constraints setup incorrectly. After taking a coffee break I figured out which ones and now the thing won't crash anymore.

like image 33
Mihai Fratu Avatar answered Sep 25 '22 10:09

Mihai Fratu