objective c - Assertion failure in -[UITableView layoutSublayersOfLayer:] on iOS 7 -


here's issue: uitableviewcontroller (with uitableview) , when there's no row, show "no content" label above.

it works on ios 8.x crashes (assertion failure) on ios 7.1.

assertion failure in -[uitableview layoutsublayersoflayer:], /sourcecache/uikit_sim/uikit-2935.137/uiview.m:8794

terminating app due uncaught exception 'nsinternalinconsistencyexception', reason: 'auto layout still required after executing -layoutsubviews. uitableview's implementation of -layoutsubviews needs call super.'

full stack:

*** assertion failure in -[uitableview layoutsublayersoflayer:], /sourcecache/uikit_sim/uikit-2935.137/uiview.m:8794 *** terminating app due uncaught exception 'nsinternalinconsistencyexception', reason: 'auto layout still required after executing -layoutsubviews. uitableview's implementation of -layoutsubviews needs 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 uncaught exception of type nsexception 

i made example project don't use storyboard or nibs. (no main.storyboard , removed entry in info.plist)

source code:

appdelegate.h

#import <uikit/uikit.h>  @interface appdelegate : uiresponder <uiapplicationdelegate>  @property (strong, nonatomic) uiwindow *window;   @end 

appdelegate.m

#import "appdelegate.h" #import "viewcontroller.h"  @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; } 

viewcontroller.h

#import <uikit/uikit.h>  @interface viewcontroller : uitableviewcontroller   @end 

viewcontroller.m

#import "viewcontroller.h"  @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 = @"hello world 42";     [self.view addsubview:centerlabel];      nsdictionary *subviews = nsdictionaryofvariablebindings(centerlabel);     [self.view addconstraints:[nslayoutconstraint constraintswithvisualformat:@"h:|[centerlabel(160)]"                                                                         options:0                                                                         metrics:nil                                                                           views:subviews]];     [self.view addconstraints:[nslayoutconstraint constraintswithvisualformat:@"v:|[centerlabel(60)]"                                                                         options:0                                                                         metrics:nil                                                                           views:subviews]]; }  @end 

read this report , refactored code use mytableview instance uitableviewcontroller:

mytableview.h

#import <uikit/uikit.h>  @interface mytableview : uitableview  @end 

mytableview.m

#import "mytableview.h"  @implementation mytableview  - (void)layoutsublayersoflayer:(calayer *)layer {     nslog(@"layoutsublayersoflayer:\n%@", [self performselector:@selector(_autolayouttrace) withobject:nil]); // compiler warning - ignore time     [super layoutsublayersoflayer:layer]; }  @end 

and overrode -uitableviewcontroller loadview method this:

- (void)loadview {     mytableview *tableview = [[mytableview alloc] initwithframe:cgrectzero style:uitableviewstyleplain];      self.view = tableview;     self.tableview = tableview; } 

here's result under ios 8.x:

2015-07-10 13:04:41.987 tableviewtest[55866:13452767] layoutsublayersoflayer:  uiwindow:0x7e06fa00 |   •mytableview:0x7db5ac00 |   |   uitableviewwrapperview:0x7db47200 |   |   *uilabel:0x7bcdb3f0'hello world 42'- ambiguous layout 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 

visual result under 8.x

here's result under ios 7.1:

2015-07-10 13:02:47.912 tableviewtest[55803:607] layoutsublayersoflayer:  *<uiwindow:0x7ae63e70> |   *<mytableview:0x7c221000> |   |   <uitableviewwrapperview:0x7b048610> |   |   *<uilabel:0x7b046f20> |   |   <uiimageview:0x7b076280> |   |   <uiimageview:0x7b079c00> 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 uncaught exception 'nsinternalinconsistencyexception', reason: 'auto layout still required after executing -layoutsubviews. mytableview's implementation of -layoutsubviews needs call super.' ... 

based on this report tried set

centerlabel.translatesautoresizingmaskintoconstraints = yes; 

but in case have no visible label (because of conflict , there's no contentview of uitableviewcontroller on uitableviewcell).

does have solution issue?

thank you,

adam

p.s.: sorry long post

in ios7, table view not add subview. view of tableviewcontroller table view


Comments