如何使用自动布局设置 tableHeaderView (UITableView) 的高度? [英] How do I set the height of tableHeaderView (UITableView) with autolayout?

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

问题描述

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

I'm been smashing my head against the wall with this for last 3 or 4 hours and I can't seem to figure it out. I have a UIViewController with a full screen UITableView inside of it (there's some other stuff on the screen, which is why I can't use a UITableViewController) and I want to get my tableHeaderView to resize with autolayout. Needless to say, it's not cooperating.

见下面的截图.

因为overviewLabel(例如在这里列出概述信息"文本)具有动态内容,我使用自动布局来调整它的大小,它是超级视图.我已经很好地调整了所有东西的大小,除了 tableHeaderView,它就在层次结构中的视差表视图的正下方.

Because the overviewLabel (e.g. the "List overview information here." text) has dynamic content, I'm using autolayout to resize it and it's superview. I've got everything resizing nicely, except for the tableHeaderView, which is right below Paralax Table View in the hiearchy.

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

The only way I've found to resize that header view is programatically, with the following code:

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

本例中headerFrameHeight是手动计算tableViewHeader高度如下(innerHeaderView为白色区域,或第二个View",headerView为tableHeaderView):

In this case, headerFrameHeight is a manual calculation of the tableViewHeader height as follows (innerHeaderView is the white area, or the second "View", headerView is 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 根据提供的约束自动调整大小,就像您可以在其他任何地方一样.但对于我的生活,我无法弄清楚.

The manual calculation works, but it's clunky and prone to error if things change in the future. What I want to be able to do is have the tableHeaderView auto-resize based on the provided constraints, like you can anywhere else. But for the life of me, I can't figure it out.

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

There's several posts on SO about this, but none are clear and ended up confusing me more. Here's a few:

tableHeaderView 的自动布局

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

使用自动布局、IB 和字体大小时表格标题视图高度错误

将 translatesAutoresizingMaskIntoConstraints 属性更改为 NO 真的没有意义,因为这只会给我带来错误,而且在概念上没有任何意义.

It doesn't really make sense to change the translatesAutoresizingMaskIntoConstraints property to NO, since that just causes errors for me and doesn't make sense conceptually anyway.

任何帮助将不胜感激!

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

EDIT 1: Thanks to TomSwift's suggestion, I was able to figure it out. Instead of manually calculating the height of the overview, I can have it calculated for me as follows and then re-set the tableHeaderView as before.

[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 中工作.下面的示例代码:

Edit 2: As others have noted, the solution posted in Edit 1 doesn't seem to work in viewDidLoad. It does, however, seem to work in viewWillLayoutSubviews. Example code below:

// 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: 方法来获取标题视图的最小边界大小.

You need to use the UIView systemLayoutSizeFittingSize: method to obtain the minimum bounding size of your header view.

我在此问答中提供了有关使用此 API 的进一步讨论:

I provide further discussion on using this API in this Q/A:

如何将超级视图调整为使用自动布局适合所有子视图?

这篇关于如何使用自动布局设置 tableHeaderView (UITableView) 的高度?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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