在tableHeaderView使用自动布局 [英] Using autolayout in a tableHeaderView

查看:904
本文介绍了在tableHeaderView使用自动布局的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个包含多行的UIView 的UILabel 。该视图使用自动布局。

I have a UIView subclass that contains a multi-line UILabel. This view uses autolayout.

我想设置这个观点为 tableHeaderView A 的UITableView 不是一节头)。此标题的高度将取决于标签,而这又取决于该装置的宽度的文本。那种场景自动布局的应该是很大的。

I would like to set this view as the tableHeaderView of a UITableView (not a section header). The height of this header will depend on the text of the label, which in turn depends on the width of the device. The sort of scenario autolayout should be great at.

我已经找到并试图<一个href=\"http://stackoverflow.com/questions/12610783/auto-layout-still-required-after-executing-layoutsubviews-with-uitableviewcel\">many <一href=\"http://stackoverflow.com/questions/16471846/is-it-possible-to-use-autolayout-with-uitableviews-tableheaderview\">many <一href=\"http://stackoverflow.com/questions/18118021/how-to-resize-superview-to-fit-all-subviews-with-autolayout\">solutions得到这个工作,但都无济于事。有些我已经试过的东西:

I have found and attempted many many solutions to get this working, but to no avail. Some of the things I've tried:


  • 设置 preferredMaxLayoutWidth 在每个标签上的 layoutSubviews

  • 定义的 intrinsicContentSize

  • 试图找出该视图所需要的尺寸和手动设置 tableHeaderView 的框架。

  • 添加一个宽度约束至视图时头被设置

  • 一堆其他的事情

  • setting a preferredMaxLayoutWidth on each label during layoutSubviews
  • defining an intrinsicContentSize
  • attempting to figure out the required size for the view and setting the tableHeaderView's frame manually.
  • adding a width constraint to the view when the header is set
  • a bunch of other things

一些我所遇到的各种故障的:

Some of the various failures I've encountered:


  • 标签超出视图的宽度,不换行

  • 框的高度为0

  • 应用程序崩溃与例外自动布局仍然需要执行-layoutSubviews后

  • label extends beyond the width of the view, doesn't wrap
  • frame's height is 0
  • app crashes with exception Auto Layout still required after executing -layoutSubviews

解决方案(或解决方案,如果需要的话)应该工作为的iOS 7和iOS 8.注意,所有这一切都被编程完成。我已经设置了如果你想破解它,看问题的一个小样本项目。我已经重置我的努力下开始点:

The solution (or solutions, if necessary) should work for both iOS 7 and iOS 8. Note that all of this is being done programmatically. I've set up a small sample project in case you want to hack on it to see the issue. I've reset my efforts to the following start point:

SCAMessageView *header = [[SCAMessageView alloc] init];
header.titleLabel.text = @"Warning";
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.";
self.tableView.tableHeaderView = header;

我是什么失踪?

推荐答案

我自己最好的答案迄今涉及设置 tableHeaderView 一次,并迫使布局传递。这使得要测量的所需的大小,这是我然后使用设置报头的帧。而且,由于是常见的有 tableHeaderView S,我必须重新设置以应用更改第二次。

My own best answer so far involves setting the tableHeaderView once and forcing a layout pass. This allows a required size to be measured, which I then use to set the frame of the header. And, as is common with tableHeaderViews, I have to again set it a second time to apply the change.

- (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 每个:

For multiline labels, this also relies on the custom view (the message view in this case) setting the preferredMaxLayoutWidth of each:

- (void)layoutSubviews
{
    [super layoutSubviews];

    self.titleLabel.preferredMaxLayoutWidth = CGRectGetWidth(self.titleLabel.frame);
    self.subtitleLabel.preferredMaxLayoutWidth = CGRectGetWidth(self.subtitleLabel.frame);
}

更新2015年1月

不幸的是这似乎仍然有必要。下面是布局过程的迅速版本:

Update January 2015

Unfortunately this still seems necessary. Here is a swift version of the layout process:

tableView.tableHeaderView = header
header.setNeedsLayout()
header.layoutIfNeeded()
let height = header.systemLayoutSizeFittingSize(UILayoutFittingCompressedSize).height
var frame = header.frame
frame.size.height = height
header.frame = frame
tableView.tableHeaderView = header

我发现它有用这个迁入上的UITableView扩展:

I've found it useful to move this into an extension on 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()
        let height = header.systemLayoutSizeFittingSize(UILayoutFittingCompressedSize).height
        var frame = header.frame
        frame.size.height = height
        header.frame = frame
        self.tableHeaderView = header
    }
}

用法:

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

这篇关于在tableHeaderView使用自动布局的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆