"Auto Layout still required after executing -layoutSubviews" with UITableViewCell subclass

Mike Mayo picture Mike Mayo · Sep 26, 2012 · Viewed 53.2k times · Source

Using XCode 4.5 and iOS 6, I'm developing an app with a simple table view with custom cells. I've done this a hundred times in iOS 5 and below, but for some reason the new autoLayout system is giving me a lot of trouble.

I setup my table view and prototype cell in IB, added subviews and wired them up as IBOutlets then setup my delegate and dataSource. However now whenever the first cell is fetched from cellForRowAtIndexPath, I get the following error:

*** Assertion failure in -[ShopCell layoutSublayersOfLayer:], /SourceCache/UIKit_Sim/UIKit-2372/UIView.m:5776

*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Auto Layout still required after executing -layoutSubviews. ShopCell's implementation of -layoutSubviews needs to call super.'

I haven't implemented a -layoutSubviews method in my subclassed cell (ShopCell), and even when I try to do that and add the super call as it suggests I still get the same error. If I remove the subviews from the cell in IB, and change it to a standard UITableViewCell, everything works as expected, though of course I'm left with no data in my cells.

I'm almost certain that there's something simple I'm missing, but can't find any documentation or guides to suggest what I've done wrong. Any help would be appreciated.

Edit: Just tried changing it to a UITableViewCell in IB and leaving all the subviews in place, still the same error.

Answer

Malaxeur picture Malaxeur · Sep 28, 2012

I encountered the same problem while manually adding constraints in code. In code, I was doing the following:

{
    [self setTranslatesAutoresizingMaskIntoConstraints:YES];
    [self addSubview:someView];
    [self addSubview:someOtherView];
    [self addConstraint:...];
}

Hypothesis

From what I can tell, the issue is that when you disable translatesAutoresizingMaskIntoConstraints, UITableViewCell starts to use Auto Layout and naturally fails because the underlying implementation of layoutSublayersForLayer does not call super. Someone with Hopper or some other tool can confirm this. Since you're using IB you're probably wondering why this is an issue... and that's because using IB automatically disables translatesAutoresizingMaskIntoConstraints for views that it adds constraints to (it will automatically add a width and height constraint in their place).

Solution

My solution was to move everything to the contentView.

{
   [self.contentView addSubview:someView];
   [self.contentView addSubview:someOtherView];
   [self.contentView addConstraint:...];
}

I'm not 100% sure if this will work in Interface Builder, but if you push everything off of your cell (assuming that you have something directly on it) then it should work. Hope this helps you!