ios - 如何使用自动布局设置 tableHeaderView (UITableView) 的高度?

标签 ios ios7 autolayout uitableview

在过去的 3 或 4 个小时里,我一直在用这个把头撞在墙上,但我似乎无法弄清楚。我有一个 UIViewController,里面有一个全屏 UITableView(屏幕上还有一些其他东西,这就是我不能使用 UITableViewController 的原因),我想让我的 tableHeaderView 使用自动布局调整大小。不用说,它不合作。

请参阅下面的屏幕截图。

enter image description here

因为 overviewLabel(例如“在此处列出概览信息。”文本)具有动态内容,我正在使用自动布局来调整它的大小并且它是 super View 。除了 tableHeaderView 之外,我已经很好地调整了所有内容的大小,它位于层次结构中视差 TableView 的正下方。

我发现调整标题 View 大小的唯一方法是通过编程方式,使用以下代码:

CGRect headerFrame = self.headerView.frame;
headerFrame.size.height = headerFrameHeight;
self.headerView.frame = headerFrame;
[self.listTableView setTableHeaderView:self.headerView];

这里headerFrameHeight是手工计算的tableViewHeader高度如下(innerHeaderView是白色区域,或者说第二个“View”,headerView是tableHeaderView):

CGFloat startingY = self.innerHeaderView.frame.origin.y + self.overviewLabel.frame.origin.y;
CGRect overviewSize = [self.overviewLabel.text
                       boundingRectWithSize:CGSizeMake(290.f, CGFLOAT_MAX)
                       options:NSStringDrawingUsesLineFragmentOrigin
                       attributes:@{NSFontAttributeName: self.overviewLabel.font}
                       context:nil];
CGFloat overviewHeight = overviewSize.size.height;
CGFloat overviewPadding = ([self.overviewLabel.text length] > 0) ? 10 : 0; // If there's no overviewText, eliminate the padding in the overall height.
CGFloat headerFrameHeight = ceilf(startingY + overviewHeight + overviewPadding + 21.f + 10.f);

手动计算可行,但它很笨拙,而且如果将来发生变化,容易出错。我想要做的是让 tableHeaderView 根据提供的约束自动调整大小,就像您在其他任何地方一样。但是对于我的生活,我无法弄清楚。

SO 上有几篇关于此的帖子,但没有一篇很清楚,最终让我更加困惑。这里有一些:

将 translatesAutoresizingMaskIntoConstraints 属性更改为 NO 没有任何意义,因为这只会给我带来错误,而且无论如何在概念上都没有意义。

非常感谢任何帮助!

编辑 1: 多亏了 TomSwift 的建议,我才弄明白了。无需手动计算概览的高度,我可以按如下方式为我计算它,然后像以前一样重新设置 tableHeaderView。

[self.headerView setNeedsLayout];
[self.headerView layoutIfNeeded];
CGFloat height = [self.innerHeaderView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height + self.innerHeaderView.frame.origin.y; // adding the origin because innerHeaderView starts partway down headerView.

CGRect headerFrame = self.headerView.frame;
headerFrame.size.height = height;
self.headerView.frame = headerFrame;
[self.listTableView setTableHeaderView:self.headerView];

编辑 2: 正如其他人所指出的,编辑 1 中发布的解决方案似乎在 viewDidLoad 中不起作用。但是,它似乎在 viewWillLayoutSubviews 中有效。示例代码如下:

// Note 1: The variable names below don't match the variables above - this is intended to be a simplified "final" answer.
// Note 2: _headerView was previously assigned to tableViewHeader (in loadView in my case since I now do everything programatically).
// Note 3: autoLayout code can be setup programatically in updateViewConstraints.
- (void)viewWillLayoutSubviews {
    [super viewWillLayoutSubviews];

    [_headerWrapper setNeedsLayout];
    [_headerWrapper layoutIfNeeded];
    CGFloat height = [_headerWrapper systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height;

    CGRect headerFrame = _headerWrapper.frame;
    headerFrame.size.height = height;
    _headerWrapper.frame = headerFrame;
    _tableView.tableHeaderView = _headerWrapper;
}

最佳答案

您需要使用 UIView systemLayoutSizeFittingSize: 方法来获取标题 View 的最小边界大小。

我在这个 Q/A 中提供了关于使用这个 API 的进一步讨论:

How to resize superview to fit all subviews with autolayout?

关于ios - 如何使用自动布局设置 tableHeaderView (UITableView) 的高度?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20982558/

相关文章:

swift - 尝试连接到我的服务器时使用 Alamofire 和 swift 出现 401 错误

iOS:带有 subview Controller 的自动布局

iOS NSLayoutConstraint 使用 constraintWithItem 固定宽度

iphone - backBarButtonItem(leftbackButtonItem) 样式问题

iOS 和 Swift - 获取一个对象的屏幕位置以设置另一个对象的位置

ios7 - 无法在 iOS 上将 CIImage 保存到文件而不发生内存泄漏

iphone - glReadPixels 仅在 iOS 7 设备上提供黑色图像

ios - 将 Controller 从 iPhone 更新到 iPad 的尺寸类别?

ios - NSUserDefaults 和 alertView

ios - 使用 Alamofire 4 的 eTag 支持