有没有可能与UITableView的tableHeaderView使用AutoLayout?
由于我发现AutoLayout
我在任何地方都使用它,现在我试图将它与tableHeaderView
一起使用。
我做了UIView
一个subclass
添加了一切(标签等),我想用他们的约束,然后我将这个CustomView
添加到UITableView
的tableHeaderView
。
一切都工作得很好,除了UITableView
始终显示上述 CustomView
,通过以上我说的是CustomView
是下 UITableView
所以它不能被看到!
看来无论我做什么, UITableView
的tableHeaderView
的height
始终为 0(宽度,x和y也是如此)。
我的问题:是否有可能完成此操作而无需手动设置框架 ?
编辑:我正在使用的CustomView
的subview
有这些约束:
_title = [[UILabel alloc]init];
_title.text = @"Title";
[self addSubview:_title];
[_title keep:[KeepTopInset rules:@[[KeepEqual must:5]]]]; // title has to stay at least 5 away from the supperview Top
[_title keep:[KeepRightInset rules:@[[KeepMin must:5]]]];
[_title keep:[KeepLeftInset rules:@[[KeepMin must:5]]]];
[_title keep:[KeepBottomInset rules:@[[KeepMin must:5]]]];
我使用的是一个方便的库'KeepLayout',因为手动编写约束需要永久性,对于单个约束而言,路线太多,但方法是自我解释的。
而UITableView
有这些限制:
_tableView = [[UITableView alloc]init];
_tableView.translatesAutoresizingMaskIntoConstraints = NO;
_tableView.delegate = self;
_tableView.dataSource = self;
_tableView.backgroundColor = [UIColor clearColor];
[self.view addSubview:_tableView];
[_tableView keep:[KeepTopInset rules:@[[KeepEqual must:0]]]];// These 4 constraints make the UITableView stays 0 away from the superview top left right and bottom.
[_tableView keep:[KeepLeftInset rules:@[[KeepEqual must:0]]]];
[_tableView keep:[KeepRightInset rules:@[[KeepEqual must:0]]]];
[_tableView keep:[KeepBottomInset rules:@[[KeepEqual must:0]]]];
_detailsView = [[CustomView alloc]init];
_tableView.tableHeaderView = _detailsView;
我不知道是否必须直接在CustomView
上设置一些约束条件,我认为CustomView
的高度取决于UILabel
“标题”的约束。
编辑2:经过另一次调查后,似乎正确计算了CustomView的高度和宽度,但CustomView的顶部仍然处于与UITableView顶部相同的级别,并且当我滚动时它们一起移动。
我在这里问及回答了一个类似的问题。 总之,我添加标题一次,并使用它来找到所需的高度。 然后可以将该高度应用于标题,并且再次设置标题以反映更改。
- (void)viewDidLoad
{
[super viewDidLoad];
self.header = [[SCAMessageView alloc] init];
self.header.titleLabel.text = @"Warning";
self.header.subtitleLabel.text = @"This is a message with enough text to span multiple lines. This text is set at runtime and might be short or long.";
//set the tableHeaderView so that the required height can be determined
self.tableView.tableHeaderView = self.header;
[self.header setNeedsLayout];
[self.header layoutIfNeeded];
CGFloat height = [self.header systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height;
//update the header's frame and set it again
CGRect headerFrame = self.header.frame;
headerFrame.size.height = height;
self.header.frame = headerFrame;
self.tableView.tableHeaderView = self.header;
}
如果您有多行标签,这也依赖于自定义视图设置每个标签的preferredMaxLayoutWidth:
- (void)layoutSubviews
{
[super layoutSubviews];
self.titleLabel.preferredMaxLayoutWidth = CGRectGetWidth(self.titleLabel.frame);
self.subtitleLabel.preferredMaxLayoutWidth = CGRectGetWidth(self.subtitleLabel.frame);
}
或者更一般地说:
override func layoutSubviews() {
super.layoutSubviews()
for view in subviews {
guard let label = view as? UILabel where label.numberOfLines == 0 else { continue }
label.preferredMaxLayoutWidth = CGRectGetWidth(label.frame)
}
}
2015年1月更新
不幸的是,这仍然是必要的 以下是布局过程的一个快速版本:
tableView.tableHeaderView = header
header.setNeedsLayout()
header.layoutIfNeeded()
header.frame.size = header.systemLayoutSizeFittingSize(UILayoutFittingCompressedSize)
tableView.tableHeaderView = header
我发现将它移动到UITableView的扩展上是非常有用的:
extension UITableView {
//set the tableHeaderView so that the required height can be determined, update the header's frame and set it again
func setAndLayoutTableHeaderView(header: UIView) {
self.tableHeaderView = header
header.setNeedsLayout()
header.layoutIfNeeded()
header.frame.size = header.systemLayoutSizeFittingSize(UILayoutFittingCompressedSize)
self.tableHeaderView = header
}
}
用法:
let header = SCAMessageView()
header.titleLabel.text = "Warning"
header.subtitleLabel.text = "Warning message here."
tableView.setAndLayoutTableHeaderView(header)
我一直无法使用约束添加一个标题视图(在代码中)。 如果我给我的观点宽度和/或高度限制,我得到一个崩溃的消息说:
"terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Auto Layout still required after executing -layoutSubviews. UITableView's implementation of -layoutSubviews needs to call super."
当我将故事板中的视图添加到我的表视图中时,它不显示约束,并且它作为标题视图正常工作,所以我认为标题视图的放置不是使用约束完成的。 在这方面,它似乎不像一个正常的观点。
宽度自动为表格视图的宽度,唯一需要设置的是高度 - 原点值将被忽略,所以放入这些内容无关紧要。 例如,这工作得很好(正如rect 0,0,0,80一样):
UIView *headerview = [[UIView alloc] initWithFrame:CGRectMake(1000,1000, 0, 80)];
headerview.backgroundColor = [UIColor yellowColor];
self.tableView.tableHeaderView = headerview;
我在这里看到很多方法做了太多不必要的事情,但在标题视图中使用自动布局并不需要那么多。 你只需要创建你的xib文件,把你的约束,并像这样实例化它:
func loadHeaderView () {
guard let headerView = Bundle.main.loadNibNamed("CourseSearchHeader", owner: self, options: nil)?[0] as? UIView else {
return
}
headerView.autoresizingMask = .flexibleWidth
headerView.translatesAutoresizingMaskIntoConstraints = true
tableView.tableHeaderView = headerView
}
链接地址: http://www.djcxy.com/p/91587.html
上一篇: Is it possible to use AutoLayout with UITableView's tableHeaderView?
下一篇: Cocoa Autolayout: content hugging vs content compression resistance priority