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

Objective CIosxcode4.5Autolayout

Objective C Problem Overview


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.

Objective C Solutions


Solution 1 - Objective C

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!

Solution 2 - Objective C

Apparently, UITableViewCell's layoutSubviews implementation does not call super, which is a problem with auto layout. I'd be interested to see if dropping the below category into projects fixes things. It helped in a test project.

#import <objc/runtime.h>
#import <objc/message.h>

@implementation UITableViewCell (FixUITableViewCellAutolayoutIHope)

+ (void)load
{
    Method existing = class_getInstanceMethod(self, @selector(layoutSubviews));
    Method new = class_getInstanceMethod(self, @selector(_autolayout_replacementLayoutSubviews));
    
    method_exchangeImplementations(existing, new);
}

- (void)_autolayout_replacementLayoutSubviews
{
    [super layoutSubviews];
    [self _autolayout_replacementLayoutSubviews]; // not recursive due to method swizzling
    [super layoutSubviews];
}

@end

I might add the problem showed up for me when using a backgroundView on the table cell, as that gets added as a subview to the cell (whereas most subviews should be added to the table cell's contentView, which should usually work better).

Note: It appears this bug is fixed in iOS7; I was able to remove this code, or at least add a runtime check so that it's only done if running on iOS6.

Solution 3 - Objective C

I had the same bug for few months. But I found what was the problem.

When I create an IB file, a UIView is already added. If you use this view, the app doesn't crash when auto layout is disabled (but there are other issues). When you use auto layout, you have to select the right view in the Object Library : UITableViewCell.

In fact, you should always use this item because all subviews are added to the contentView of the UITableViewCell.

That's all. All will be fine.

Solution 4 - Objective C

I had same trouble with custom UITableViewHeaderFooterView + xib.

I saw some answers here, but I found what implementation -layoutSubviews in my custom footer view class fixes issue:

-(void)layoutSubviews
{
    [super layoutSubviews];
    [self layoutIfNeeded]; // this line is key
}

Solution 5 - Objective C

I was seeing this as a result of modifying constraints in my implementation of layoutSubviews. Moving the call to super from the beginning to the end of the method fixed the problem.

Solution 6 - Objective C

Had the same problem in iOS 7 (iOS 8 seems to fix). The solution for me was to call [self.view layoutIfNeeded] at the end of my viewDidLayoutSubviews method.

Solution 7 - Objective C

I had the same issue. The problem was in the way I was creating the cell Xib. I created a Xib like normal and just changed the type of the default "UIView" to my custom UITableViewCell class. The correct way to is to first delete the default view and then drag the table view cell object onto the xib. More details here : http://allplayers.github.io/blog/2012/11/18/Custom-UITableViewCell-With-NIB/

Solution 8 - Objective C

I resolved the issue by turning off "Autolayout" for all the subviews of my custom Table View Cell.

In the xib for a custom cell, select a subview and uncheck File Inspector > Interface Builder Document > Use Autolayout

Solution 9 - Objective C

I had a similar problem not on UITableViewCell but rather on UITableView itself. Because it is the first result in Google I'll post it here. It turned out that viewForHeaderInSection was the problem. I created a UITableViewHeaderFooterView and set translatesAutoresizingMaskIntoConstraints to NO. Now here comes the interesting part:

iOS 7:

// don't do this on iOS 7
sectionHeader.translatesAutoresizingMaskIntoConstraints = NO;

If I do this the app crashes with

> Auto Layout still required after executing -layoutSubviews. > UITableView's implementation of -layoutSubviews needs to call super.

OK, I thought you can't use auto layout on a table view header and only on the subviews. But that's not the full truth as you see it later. To sum up: Don't disable auto resizing mask for the header on iOS 7. Otherwise it's working fine.

iOS 8:

// you have to do this, otherwise you get an auto layout error
sectionHeader.translatesAutoresizingMaskIntoConstraints = NO;

If I wouldn't use this I'd get the following output:

> Unable to simultaneously satisfy constraints.

For iOS 8 you have to disable auto resizing mask for the header.

Don't know why it behaves in this way but it seems that Apple did fix some things in iOS 8 and auto layout is working differently on iOS 7 and iOS 8.

Solution 10 - Objective C

As someone above has already stated, when you create a view for use in a UITableView, you have to delete the view created by default and drag a UITableViewCell or UITableViewHeaderFooterView as the root view. However, there is a way to fix the XIB in case you had missed that part. You have to open the XIB file in a text editor and in the root tag and its direct child add/change the attribute translatesAutoresizingMaskIntoConstraints to YES, for example

<view contentMode="scaleToFill" horizontalHuggingPriority="1000" id="1" translatesAutoresizingMaskIntoConstraints="YES" customClass="MXWCollapsibleTableHeaderView">

Solution 11 - Objective C

I am encountering this and it seems that it is related to UITableViewCell subclasses as prototype cells that specifically have other custom UIView subclasses added to them. I stress the 'custom' here because I have been successful with cells that just have UIKit children, but it falls over when trying to build the constraints for views I have created bespoke, throwing the error stated in the authors question.

I have had to separate my cells into independent nibs that don't use AutoLayout.

Let's hope Apple clean up this mess.

Solution 12 - Objective C

Add your subviews to the contentView of the cell instead of the cell itself. So instead of:

[self addSubview:someView];

you must use

[self.contentView addSubview:someView];

Solution 13 - Objective C

I encountered this one because I had initially added a UIView instead of a UITableViewCell to a xib file.

Solution 14 - Objective C

I eliminated this error by uncoupling the backgroundView connector from my background UIImageView and accessoryView connector from my UIButton customisations. I suspect that these were not meant to be used the way I was using them.

Solution 15 - Objective C

I had run into this issue first time today. Up until now I had some various experience in using prototype UITableViewCell subclasses but never ran into this issue. What was different about the cell I was working with was that I had an IBOutlet to the -backgroundView which I was using to color the cell. I found that if I created a new property and still added a fresh UIView which stretched the span of the entire cell, this assertion went away. To verify this was the cause, I went back to attaching this view to the backgroundView outlet and the assertion reappeared. So far, no other issues using AutoLayout in a subclassed prototype UITableViewCell since I've made this change.

Solution 16 - Objective C

I didn't get any proper solution for this issue but you can fix it by using frames and not setting translatesAutoresizingMaskIntoConstraints property to No (by default its yes, so don't set it)

CGRect headerViewFrame = CGRectMake(0,0,320,60); //Frame for your header/footer view
UIView *tableHeaderView = [[UIView alloc] initWithFrame:headerViewFrame];
tableHeaderView.translatesAutoresizingMaskIntoConstraints = Yes; //Or don't set it at all
[self.tableView setTableHeaderView:tableHeaderView];

Solution 17 - Objective C

I have been experiencing the same thing. It turned out that if you programmatically add a subview from your ShopCell .xib/storyboard, that uses auto layout, as a subview to another view, that exception might be thrown, depending on how your constraints are configured. My guess is that the constraints created in IB is what creates the troubles when programmatically adding a view as a subview, since it's then maintaing constraints from viewA --> viewB meanwhile you might add viewB as a subview of viewC. You got it (that sentence is even confusing myself)?

In my situation - since it was very simple views that caused the problem - I created the views programmatically and not in IB. That solved it. You might extract those views to other xib files and disable auto layout for those. I guess that'd work.

Solution 18 - Objective C

In some situations, this solves the layout problem easily (depending on your layout). Inside you UITableView subclass, in either awakeFromNib or init, set the autoresizing mask:

self.contentView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;

By defaut it is set to UIViewAutoresizingNone

Solution 19 - Objective C

In my case,

The referenced UIImageView for the auto layout for UITableView is assigned to backgroundView of the UITableView.

self.tableView.backgroundView = self.tableBackgroundImageView;

So, I removed UIImageView for backgroundView from the UIView(Root view) and reset(remove) all auto layout reference to that UIImageView. I placed that UIImageView for background at the outside from the UIView(root view). And then assign to the backgroundView of the UITableView in code.

Then fixed.

Solution 20 - Objective C

I have found the solution.

In my case, I created cell's view in storyboard (with auto layout enabled) and I defined the custom UITableViewCell interface in my ViewController.m, I have to move interface to ViewController.h.

Solution 21 - Objective C

I encountered the same problem when I use the storyboard to create the custom UITableViewCell. Fortunately I found the problem, because I outlet the accessoryView([UITableViewCell setAccessoryView:]) to UIButton which I added to the cell.

> So it occurred in my project when run on the iOS6.

Solution

> I release the outlet between accessoryView and my button which > contained the custom cell.

Proposal

> You shouldn't used the UITableViewCell's native elements and change > it.

Solution 22 - Objective C

This problem can be caused by forgetting to call [super viewDidAppear:] within viewDidAppear, but I'm sure it's not the only cause.

Solution 23 - Objective C

I had exact the same problem. Here is the problem with my project:
When I worked on the Interface Builder to create a custom UITableViewCell, I dragged a View instead of a Table View Cell from the object collection pane in Xcode
as the custom table cell.
If you are in the same situation, here is the solution:
Delete the view in interface builder, make sure you drag a Table View Cell from the object collection pane and redo the custom table cell view. You can copy the objects in the old view and paste them to the canvas for the new Table View Cell.

Solution 24 - Objective C

I had a very similar problem with a table footer view I was setting in Xcode 6, iOS 7+. The solution was in the format of the nib file. Apparently it was stuck in Xcode 4 format or something. Changing the file settings to "opens in: Xcode 6.0" (or Default, for that matter), instantly fixed it. Found the solution by chance: it was driving me crazy, so I deleted the entire file and created again, obviously with the default settings. I have no idea why simply editing the file in the latest Xcode didn't convert it to a Xcode 5+ format, as it usually happens.

f

Solution 25 - Objective C

I went had the same issue. I went to my DetailViewController and renamed the identifier to UIView. It was previously on UITableView. It fixed the problem. This problem doesn't have to be in your DetailViewController. It could be in any other one. Try renaming it to the respected identifier.

Solution 26 - Objective C

I had a similar issue with static table view cells in IB. One of the cells had a subview that had a class that was mistakenly altered to a subclass of UITextfield. The compiler didn't give any warnings/errors. But at runtime the system was unable to load the view controller with the aforementioned crash as a result.

Solution 27 - Objective C

Issue is sequencing of the layout calls to the subviews:

Check out

Shows up in iOS < 8

Solution 28 - Objective C

Solution: change constraints before call super layoutSubviews

- (void)layoutSubviews
{
    
    [self _updateConstraints];

    [super layoutSubviews];
}

Solution 29 - Objective C

I modified Carl Lindberg's answer to override UITableView instead and it started working for me:

UITableView+AutoLayoutFix.h

@interface UITableView (AutoLayoutFix)
@end

UITableView+AutoLayoutFix.m

#import <objc/runtime.h>

@implementation UITableView (AutoLayoutFix)

+ (void)load
{
    Method existingMethod = class_getInstanceMethod(self, @selector(layoutSubviews));
    Method newMethod = class_getInstanceMethod(self, @selector(_autolayout_replacementLayoutSubviews));

    method_exchangeImplementations(existingMethod, newMethod);
}

- (void)_autolayout_replacementLayoutSubviews
{
    [super layoutSubviews];
    [self _autolayout_replacementLayoutSubviews]; // not recursive due to method swizzling
    [super layoutSubviews];
}

@end

Then in MyViewController.m I just imported the category:

#import "UITableView+AutoLayoutFix.h"

Solution 30 - Objective C

I met the same problem and finally found the reason was that I added one constraint to the UITableViewCell, which should be the UITableViewCell's contentView. When I changed the constraint everything went fine!

Solution 31 - Objective C

I had the same problem , changing from UIView to UITableViewCell solved the problem.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMike MayoView Question on Stackoverflow
Solution 1 - Objective CMalaxeurView Answer on Stackoverflow
Solution 2 - Objective CCarl LindbergView Answer on Stackoverflow
Solution 3 - Objective CArnaudView Answer on Stackoverflow
Solution 4 - Objective CSound BlasterView Answer on Stackoverflow
Solution 5 - Objective CPhil LodenView Answer on Stackoverflow
Solution 6 - Objective CKellerView Answer on Stackoverflow
Solution 7 - Objective CTrunal BhanseView Answer on Stackoverflow
Solution 8 - Objective CJohnoView Answer on Stackoverflow
Solution 9 - Objective CtestingView Answer on Stackoverflow
Solution 10 - Objective CMaksymilian WojakowskiView Answer on Stackoverflow
Solution 11 - Objective CLee ProbertView Answer on Stackoverflow
Solution 12 - Objective CChristian AbergerView Answer on Stackoverflow
Solution 13 - Objective CmjmdavisView Answer on Stackoverflow
Solution 14 - Objective COwen GodfreyView Answer on Stackoverflow
Solution 15 - Objective CEric SchrammView Answer on Stackoverflow
Solution 16 - Objective CsanjanaView Answer on Stackoverflow
Solution 17 - Objective CKasper MunckView Answer on Stackoverflow
Solution 18 - Objective CArie LitovskyView Answer on Stackoverflow
Solution 19 - Objective CConan KimView Answer on Stackoverflow
Solution 20 - Objective CNim ThitipariwatView Answer on Stackoverflow
Solution 21 - Objective CjiwqView Answer on Stackoverflow
Solution 22 - Objective CmichaelsnowdenView Answer on Stackoverflow
Solution 23 - Objective Cus_davidView Answer on Stackoverflow
Solution 24 - Objective Cuser3099609View Answer on Stackoverflow
Solution 25 - Objective CRandomDudeView Answer on Stackoverflow
Solution 26 - Objective CYannick WintersView Answer on Stackoverflow
Solution 27 - Objective CShanu jiView Answer on Stackoverflow
Solution 28 - Objective CabuharskyView Answer on Stackoverflow
Solution 29 - Objective CplowmanView Answer on Stackoverflow
Solution 30 - Objective CAlfyView Answer on Stackoverflow
Solution 31 - Objective CbantyView Answer on Stackoverflow