UITableView Header 上的自动布局
Posted
技术标签:
【中文标题】UITableView Header 上的自动布局【英文标题】:Auto layout on UITableViewHeader 【发布时间】:2013-01-31 23:56:40 【问题描述】:我已向 Apple 提交了关于此问题的错误报告!
我正在尝试在我的 UITableViewHeader 上使用新的 ios 6 自动布局,但我扔给它的所有内容都会在帖子末尾出现错误。
我的代码:
TBMTableViewController.h
#import <UIKit/UIKit.h>
@interface TBMTableViewController : UIViewController <UITableViewDataSource, UITableViewDelegate>
@end
TBMTableViewController.m
#import "TBMTableViewController.h"
#import "UIView+Constraint.h"
@implementation TBMTableViewController
- (void)viewDidLoad
[super viewDidLoad];
UITableViewController *tableViewController = [[UITableViewController alloc] initWithStyle:UITableViewStylePlain];
[tableViewController.tableView setTranslatesAutoresizingMaskIntoConstraints:NO];
UITableView *tableView = tableViewController.tableView;
[tableView setTranslatesAutoresizingMaskIntoConstraints:NO];
[tableView setDelegate:self];
[tableView setDataSource:self];
[self.view addSubview:tableView];
UIView *headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 200.0f)];
[headerView setTranslatesAutoresizingMaskIntoConstraints:NO];
[tableView setTableHeaderView:headerView];
UIButton *btn1 = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[btn1 setTranslatesAutoresizingMaskIntoConstraints:NO];
[btn1 setTitle:@"Button 1" forState:UIControlStateNormal];
[btn1 sizeToFit];
[headerView addSubview:btn1];
UIButton *btn2 = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[btn2 setTranslatesAutoresizingMaskIntoConstraints:NO];
[btn2 setTitle:@"Button 2" forState:UIControlStateNormal];
[btn2 sizeToFit];
[headerView addSubview:btn2];
NSDictionary *views = NSDictionaryOfVariableBindings(tableView, headerView, btn1, btn2);
[self.view addVisualConstraints:@"H:|[tableView]|" forViews:views];
[self.view addVisualConstraints:@"V:|[tableView]|" forViews:views];
[headerView addVisualConstraints:@"H:[btn1]-|" forViews:views];
[headerView addVisualConstraints:@"V:|-[btn1]" forViews:views];
[headerView addVisualConstraints:@"H:[btn2]-|" forViews:views];
[headerView addVisualConstraints:@"V:[btn1]-[btn2]" forViews:views];
[headerView addVisualConstraints:@"[btn2(==btn1)]" forViews:views];
@end
UIView+Constraint.m
- (void)addVisualConstraints:(NSString *)constraintString forViews:(NSDictionary *)views
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:constraintString
options:0
metrics:0
views:views]];
错误:
2013-02-01 00:43:34.481 ConstraintTest[10217:c07] *** Assertion failure in
-[UITableView layoutSublayersOfLayer:],
/SourceCache/UIKit_Sim/UIKit-2380.17/UIView.m:5776
2013-02-01 00:43:34.483 ConstraintTest[10217:c07] *** 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:
(0x1c94012 0x10d1e7e 0x1c93e78 0xb67665 0x6639f 0x10e56b0 0x2290fc0 0x228533c
0x2290eaf 0x1052bd 0x4db56 0x4c66f 0x4c589 0x4b7e4 0x4b61e 0x4c3d9 0x4f2d2
0xf999c 0x46574 0x4676f 0x46905 0x4f917 0x2b15 0x13157 0x13747 0x1494b 0x25cb5
0x26beb 0x18698 0x1befdf9 0x1befad0 0x1c09bf5 0x1c09962 0x1c3abb6 0x1c39f44
0x1c39e1b 0x1417a 0x15ffc 0x28dd 0x2805)
libc++abi.dylib: terminate called throwing an exception
(lldb)
我已经尝试了我能想到的一切。甚至谷歌也无法提供答案。我已经删除了不相关的代码,例如 UITableViewDataSource- 和 UITableViewDelegate 方法以进行澄清。不涉及任何 nib,我的 appDelegate 唯一要做的就是初始化 TBMTableViewController 并将其设置为 rootViewController。
编辑: 我更新了我的 viewDidLoad 方法,以阐明我想对 UITableViewHeader 内的控件使用约束,而不是标题本身。同样的错误:)
【问题讨论】:
表头视图是否需要设置约束?它们自动与表格的宽度相同,并放置在顶部——您唯一可以控制的是高度。 视觉约束只是一个例子。我对在标题视图中向 ui 控件添加视觉约束更感兴趣,例如图像视图、按钮等。抱歉没有说清楚 我已经做到了,我认为应该可以正常工作。试图让他们上桌是一件麻烦(而且不必要)的事情。 只是为了测试,我尝试让我的表格视图标题成为 UIView 的子类,然后在我的 TableViewController 中只使用 initWithFrame 并且错误仍然相同。如果我只是删除表格视图并使用我的新 HeaderView 类,它会按预期工作。 【参考方案1】:这对我来说是一个非常愚蠢的错误。当我删除这些行时,我最终得到了一切工作:
[tableView setTranslatesAutoresizingMaskIntoConstraints:NO];
和
[headerView setTranslatesAutoresizingMaskIntoConstraints:NO];
【讨论】:
虽然这解决了你的问题,但它确实引发了关于这行代码的一个重要问题:你到底是如何使用这段代码来解决模棱两可的布局问题的!?! [headerView layoutSubviews];调用 addSubview 时调用它 只是为了记录,我在代码中做我所有的标题,并使用 NSLayoutContraint 对象。正是上面的第二条语句阻止了我在 iOS7 中的崩溃。【参考方案2】:我在同一个视图控制器中同时使用了viewWillLayoutSubviews
和viewDidLayoutSubviews
,在使用单个viewWillLayoutSubviews
进行管理后,它对我有用。
【讨论】:
以上是关于UITableView Header 上的自动布局的主要内容,如果未能解决你的问题,请参考以下文章
UITableView Section Header导航时跳转
动态布局UITableView的cell , header , footer
如何根据ios 8中的内容动态调整UITableview Header高度