有没有可能与UITableView的tableHeaderView使用AutoLayout?

由于我发现AutoLayout我在任何地方都使用它,现在我试图将它与tableHeaderView一起使用。

我做了UIView一个subclass添加了一切(标签等),我想用他们的约束,然后我将这个CustomView添加到UITableViewtableHeaderView

一切都工作得很好,除了UITableView始终显示上述 CustomView ,通过以上我说的是CustomView UITableView所以它不能被看到!

看来无论我做什么, UITableViewtableHeaderViewheight 始终为 0(宽度,x和y也是如此)。

我的问题:是否有可能完成此操作而无需手动设置框架

编辑:我正在使用的CustomViewsubview有这些约束:

_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