iOS 7 上的 -[UITableView layoutSublayersOfLayer:] 中的断言失败
Posted
技术标签:
【中文标题】iOS 7 上的 -[UITableView layoutSublayersOfLayer:] 中的断言失败【英文标题】:Assertion failure in -[UITableView layoutSublayersOfLayer:] on iOS 7 【发布时间】:2015-07-10 12:19:07 【问题描述】:问题是:UITableViewController(带有 UITableView),当没有行时,我想在上面显示一个“无内容”标签。
它适用于 iOS 8.x,但 崩溃(断言失败)适用于 iOS 7.1。
-[UITableView layoutSublayersOfLayer:] 中的断言失败, /SourceCache/UIKit_Sim/UIKit-2935.137/UIView.m:8794
由于未捕获的异常而终止应用 'NSInternalInconsistencyException',原因:'自动布局仍然 执行 -layoutSubviews 后需要。 UITableView 的实现 的 -layoutSubviews 需要调用 super。'
全栈:
*** 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
我做了一个不使用故事板或笔尖的示例项目。 (没有 Main.storyboard 并删除了 Info.plist 中的条目)
源代码:
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
阅读 this report 并重构我的代码以将 MyTableView 实例用于 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 for this time
[super layoutSublayersOfLayer:layer];
@end
并像这样覆盖 -UITableViewController loadView 方法:
- (void)loadView
MyTableView *tableView = [[MyTableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain];
self.view = tableView;
self.tableView = tableView;
这是 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 for UILabel:0x7bcdb3f0'Hello World 42'.minXid: 3, UILabel:0x7bcdb3f0'Hello World 42'.minYid: 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
这是 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 to uncaught exception 'NSInternalInconsistencyException', reason: 'Auto Layout still required after executing -layoutSubviews. MyTableView's implementation of -layoutSubviews needs to call super.'
...
基于this report我也尝试设置
centerLabel.translatesAutoresizingMaskIntoConstraints = YES;
但在这种情况下,我没有可见的标签(因为冲突,并且没有 UITableViewController 的 contentView,就像 UITableViewCell 上一样)。
有人有解决这个问题的办法吗?
谢谢,
亚当
P.S.:很抱歉发了这么长的帖子
【问题讨论】:
可能是这个link对你有帮助 @Adam Szabo,您似乎遇到了一些问题,您想解决哪一个? @Anbu.Karthik 尝试将所有 centerLabel 设置 + 约束移动到 viewWillAppear: & viewDidAppear: 中,但同样的断言失败。 @A-Live 对不起,但不确定你在“几个问题”下是什么意思 - 我想为 UITableView 添加一个子视图,它在 iOS 7 下具有自动布局约束。X。顺便说一句,如果我删除约束并使用 frame + autoresizingMasks 它工作正常。 【参考方案1】:在 iOS7 中,表格视图无法添加子视图。 tableViewController 的一个视图就是表视图
【讨论】:
以上是关于iOS 7 上的 -[UITableView layoutSublayersOfLayer:] 中的断言失败的主要内容,如果未能解决你的问题,请参考以下文章
iOS 7 上的 UIBarButtonSystemItemRefresh
iOS 7 上的 UIImagePickerController:方形模式?
iOS 6 和 iOS 7 上的 UICollectionView 重新加载