iphone - 是否可以将 AutoLayout 与 UITableView 的 tableHeaderView 一起使用?

标签 iphone ios ipad uitableview autolayout

自从我发现 AutoLayout 以来,我到处都在使用它,现在我正尝试将它与 tableHeaderView 一起使用。

我制作了 UIView子类 添加了我想要的所有内容(标签等...)和它们的约束,然后我添加了这个 CustomViewUITableView'tableHeaderView

除了 UITableView 总是显示 above CustomView 之外,一切正常,above 我的意思是 CustomView 位于 UITableView 下,所以看不到!

似乎无论我做什么,UITableView'tableHeaderViewheight 都是总是 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 的顶部处于同一水平,并且它们移动当我滚动时一起。

最佳答案

我问并回答了一个类似的问题here .总之,我添加了一次表头并使用它来找到所需的高度。然后可以将该高度应用到页眉,并第二次设置页眉以反射(reflect)更改。

- (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;
}

如果你有多行标签,这也依赖于自定义 View 设置每个标签的 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
        self.tableHeaderView?.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            header.widthAnchor.constraint(equalTo: self.widthAnchor)
        ])
        header.setNeedsLayout()
        header.layoutIfNeeded()
        header.frame.size =  header.systemLayoutSizeFitting(UIView.layoutFittingCompressedSize)
        self.tableHeaderView = header
    }
}

用法:

let header = SCAMessageView()
header.titleLabel.text = "Warning"
header.subtitleLabel.text = "Warning message here."
tableView.setAndLayoutTableHeaderView(header)

关于iphone - 是否可以将 AutoLayout 与 UITableView 的 tableHeaderView 一起使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16471846/

相关文章:

iphone - xibs 问题 : should I use @2x 中的 UIImage 名称

iphone - 添加 TableView subview 会使应用程序崩溃

iOS谷歌VR SDK : Unable to preview Video

ios - 'NSInvalidArgumentException',原因 : '*** -[NSURL initFileURLWithPath:]: nil string parameter'

iphone - 呈现图像裁剪界面

ios - 如何使用 AFNetworking 3.0 在后台下载大文件并在 session 完成所有任务时显示本地通知

javascript - iPhone/iPad 上的 session 存储可以持续多长时间?

ios - 我可以在不实时插入 XCode 的情况下在 iPhone 上模拟我的位置吗?

ios - Xml 解析器委托(delegate)未在 Swift 中调用

ios - 将数据从结构数组传递到新的 TableView Controller