title: Assertion failure in -[UITableView layoutSublayersOfLayer:] on iOS 7
body: <p>Here's the issue: UITableViewController (with UITableView) and when there's no row, I would like to show a &quot;No content&quot; label above.</p>
  <p>It <strong>works on iOS 8.x</strong> but <strong>crashes</strong> (assertion failure) <strong>on iOS 7.1</strong>.</p>
  <blockquote>
  <p>Assertion failure in -[UITableView layoutSublayersOfLayer:],
  /SourceCache/UIKit_Sim/UIKit-2935.137/UIView.m:8794</p>
  <p>Terminating app due to uncaught exception
  'NSInternalInconsistencyException', reason: 'Auto Layout still
  required after executing -layoutSubviews. UITableView's implementation
  of -layoutSubviews needs to call super.'</p>
  </blockquote>
  <p>Full stack:</p>
  <pre><code>*** Assertion failure in -[UITableView layoutSublayersOfLayer:], /SourceCache/UIKit_Sim/UIKit-2935.137/UIView.m:8794
  *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Auto Layout still required after executing -layoutSubviews. UITableView's implementation of -layoutSubviews needs to call super.'
  *** First throw call stack:
  (
      0   CoreFoundation                      0x007fb1e4 __exceptionPreprocess + 180
      1   libobjc.A.dylib                     0x0057a8e5 objc_exception_throw + 44
      2   CoreFoundation                      0x007fb048 +[NSException raise:format:arguments:] + 136
      3   Foundation                          0x0015a4de -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 116
      4   UIKit                               0x00cdea38 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 567
      5   libobjc.A.dylib                     0x0058c82b -[NSObject performSelector:withObject:] + 70
      6   QuartzCore                          0x044eb45a -[CALayer layoutSublayers] + 148
      7   QuartzCore                          0x044df244 _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE + 380
      8   QuartzCore                          0x044eb3a5 -[CALayer layoutIfNeeded] + 160
      9   UIKit                               0x00da0ae3 -[UIViewController window:setupWithInterfaceOrientation:] + 304
      10  UIKit                               0x00cb6aa7 -[UIWindow _setRotatableClient:toOrientation:updateStatusBar:duration:force:isRotating:] + 5212
      11  UIKit                               0x00cb5646 -[UIWindow _setRotatableClient:toOrientation:updateStatusBar:duration:force:] + 82
      12  UIKit                               0x00cb5518 -[UIWindow _setRotatableViewOrientation:updateStatusBar:duration:force:] + 117
      13  UIKit                               0x00cb55a0 -[UIWindow _setRotatableViewOrientation:duration:force:] + 67
      14  UIKit                               0x00cb463a __57-[UIWindow _updateToInterfaceOrientation:duration:force:]_block_invoke + 120
      15  UIKit                               0x00cb459c -[UIWindow _updateToInterfaceOrientation:duration:force:] + 400
      16  UIKit                               0x00cb52f3 -[UIWindow setAutorotates:forceUpdateInterfaceOrientation:] + 870
      17  UIKit                               0x00cb88e6 -[UIWindow setDelegate:] + 449
      18  UIKit                               0x00d92b77 -[UIViewController _tryBecomeRootViewControllerInWindow:] + 180
      19  UIKit                               0x00cae474 -[UIWindow addRootViewControllerViewIfPossible] + 591
      20  UIKit                               0x00cae5ef -[UIWindow _setHidden:forced:] + 312
      21  UIKit                               0x00cae86b -[UIWindow _orderFrontWithoutMakingKey] + 49
      22  UIKit                               0x00cb93c8 -[UIWindow makeKeyAndVisible] + 65
      23  tableviewtest                       0x000eea0a -[AppDelegate application:didFinishLaunchingWithOptions:] + 554
      24  UIKit                               0x00c6914f -[UIApplication _handleDelegateCallbacksWithOptions:isSuspended:restoreState:] + 309
      25  UIKit                               0x00c69aa1 -[UIApplication _callInitializationDelegatesForURL:payload:suspended:] + 1810
      26  UIKit                               0x00c6e667 -[UIApplication _runWithURL:payload:launchOrientation:statusBarStyle:statusBarHidden:] + 824
      27  UIKit                               0x00c82f92 -[UIApplication handleEvent:withNewEvent:] + 3517
      28  UIKit                               0x00c83555 -[UIApplication sendEvent:] + 85
      29  UIKit                               0x00c70250 _UIApplicationHandleEvent + 683
      30  GraphicsServices                    0x02cc7f02 _PurpleEventCallback + 776
      31  GraphicsServices                    0x02cc7a0d PurpleEventCallback + 46
      32  CoreFoundation                      0x00776ca5 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 53
      33  CoreFoundation                      0x007769db __CFRunLoopDoSource1 + 523
      34  CoreFoundation                      0x007a168c __CFRunLoopRun + 2156
      35  CoreFoundation                      0x007a09d3 CFRunLoopRunSpecific + 467
      36  CoreFoundation                      0x007a07eb CFRunLoopRunInMode + 123
      37  UIKit                               0x00c6dd9c -[UIApplication _run] + 840
      38  UIKit                               0x00c6ff9b UIApplicationMain + 1225
      39  tableviewtest                       0x000eed4a main + 138
      40  libdyld.dylib                       0x028fa6d9 start + 1
      41  ???                                 0x00000001 0x0 + 1
  )
  libc++abi.dylib: terminating with uncaught exception of type NSException
  </code></pre>
  <p>I made an example project where I don't use storyboard or nibs. (No Main.storyboard and removed the entry in Info.plist)</p>
  <p>Source code:</p>
  <p>AppDelegate.h</p>
  <pre><code>#import &lt;UIKit/UIKit.h&gt;
  
  @interface AppDelegate : UIResponder &lt;UIApplicationDelegate&gt;
  
  @property (strong, nonatomic) UIWindow *window;
  
  
  @end
  </code></pre>
  <p>AppDelegate.m</p>
  <pre><code>#import &quot;AppDelegate.h&quot;
  #import &quot;ViewController.h&quot;
  
  @interface AppDelegate ()
  
  @end
  
  @implementation AppDelegate
  
  
  - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
      ViewController *viewController = [[ViewController alloc] init];
      
      self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
      [self.window setRootViewController:viewController];
      [self.window makeKeyAndVisible];
      
      return YES;
  }
  </code></pre>
  <p>ViewController.h</p>
  <pre><code>#import &lt;UIKit/UIKit.h&gt;
  
  @interface ViewController : UITableViewController
  
  
  @end
  </code></pre>
  <p>ViewController.m</p>
  <pre><code>#import &quot;ViewController.h&quot;
  
  @interface ViewController ()
  
  @end
  
  @implementation ViewController
  
  - (void)viewDidLoad {
      [super viewDidLoad];
      
      self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
      
      UILabel *centerLabel = [[UILabel alloc] initWithFrame:CGRectZero];
      centerLabel.translatesAutoresizingMaskIntoConstraints = NO;
      centerLabel.backgroundColor = [UIColor grayColor];
      centerLabel.text = @&quot;Hello World 42&quot;;
      [self.view addSubview:centerLabel];
      
      NSDictionary *subviews = NSDictionaryOfVariableBindings(centerLabel);
      [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@&quot;H:|[centerLabel(160)]&quot;
                                                                          options:0
                                                                          metrics:nil
                                                                            views:subviews]];
      [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@&quot;V:|[centerLabel(60)]&quot;
                                                                          options:0
                                                                          metrics:nil
                                                                            views:subviews]];
  }
  
  @end
  </code></pre>
  <p>Read <a href="https://stackoverflow.com/questions/23020326/assertion-failure-in-uitableview-layoutsublayersoflayer">this report</a> and refactored my code to use MyTableView instance for the UITableViewController:</p>
  <p>MyTableView.h</p>
  <pre><code>#import &lt;UIKit/UIKit.h&gt;
  
  @interface MyTableView : UITableView
  
  @end
  </code></pre>
  <p>MyTableView.m</p>
  <pre><code>#import &quot;MyTableView.h&quot;
  
  @implementation MyTableView
  
  - (void)layoutSublayersOfLayer:(CALayer *)layer
  {
      NSLog(@&quot;layoutSublayersOfLayer:\n%@&quot;, [self performSelector:@selector(_autolayoutTrace) withObject:nil]); // compiler warning - ignore for this time
      [super layoutSublayersOfLayer:layer];
  }
  
  @end
  </code></pre>
  <p>And overrode -UITableViewController loadView method like this:</p>
  <pre><code>- (void)loadView
  {
      MyTableView *tableView = [[MyTableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain];
      
      self.view = tableView;
      self.tableView = tableView;
  }
  </code></pre>
  <p>Here's the result under iOS 8.x:</p>
  <pre><code>2015-07-10 13:04:41.987 tableviewtest[55866:13452767] layoutSublayersOfLayer:
  
  UIWindow:0x7e06fa00
  |   •MyTableView:0x7db5ac00
  |   |   UITableViewWrapperView:0x7db47200
  |   |   *UILabel:0x7bcdb3f0'Hello World 42'- AMBIGUOUS LAYOUT for UILabel:0x7bcdb3f0'Hello World 42'.minX{id: 3}, UILabel:0x7bcdb3f0'Hello World 42'.minY{id: 8}
  |   |   UIImageView:0x7bceab00
  |   |   UIImageView:0x7bceb9a0
  2015-07-10 13:04:41.988 tableviewtest[55866:13452767] layoutSublayersOfLayer:
  
  UIWindow:0x7e06fa00
  |   •MyTableView:0x7db5ac00
  |   |   UITableViewWrapperView:0x7db47200
  |   |   *UILabel:0x7bcdb3f0'Hello World 42'
  |   |   UIImageView:0x7bceab00
  |   |   UIImageView:0x7bceb9a0
  </code></pre>
  <p><img src="https://i.stack.imgur.com/qZFOE.png" alt="Visual result under 8.x" /></p>
  <p>Here's the result under iOS 7.1:</p>
  <pre><code>2015-07-10 13:02:47.912 tableviewtest[55803:607] layoutSublayersOfLayer:
  
  *&lt;UIWindow:0x7ae63e70&gt;
  |   *&lt;MyTableView:0x7c221000&gt;
  |   |   &lt;UITableViewWrapperView:0x7b048610&gt;
  |   |   *&lt;UILabel:0x7b046f20&gt;
  |   |   &lt;UIImageView:0x7b076280&gt;
  |   |   &lt;UIImageView:0x7b079c00&gt;
  2015-07-10 13:06:27.886 tableviewtest[55911:607] *** Assertion failure in -[MyTableView layoutSublayersOfLayer:], /SourceCache/UIKit_Sim/UIKit-2935.137/UIView.m:8794
  2015-07-10 13:06:27.889 tableviewtest[55911:607] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Auto Layout still required after executing -layoutSubviews. MyTableView's implementation of -layoutSubviews needs to call super.'
  ...
  </code></pre>
  <p>Based on <a href="https://stackoverflow.com/questions/12610783/auto-layout-still-required-after-executing-layoutsubviews-with-uitableviewcel">this report</a> I also tried to set</p>
  <pre><code>centerLabel.translatesAutoresizingMaskIntoConstraints = YES;
  </code></pre>
  <p>but in that case I have no visible label (because of a conflict and there's no contentView of UITableViewController like on a UITableViewCell).</p>
  <p>Does anybody have a solution for this issue?</p>
  <p>Thank you,</p>
  <p>Adam</p>
  <p>P.S.: Sorry for the long post</p>