Как установить высоту tableHeaderView (UITableView) с помощью автоматического размещения?
Я бился головой об стену с этим последние 3 или 4 часа, и я не могу понять это. У меня есть UIViewController с полноэкранным UITableView внутри (есть некоторые другие вещи на экране, поэтому я не могу использовать UITableViewController), и я хочу получить свой tableHeaderView для изменения размера с autolayout. Излишне говорить, что это не сотрудничество.
Смотрите скриншот ниже.
Так как OverviewLabel (например, текст «Перечень обзорной информации здесь.») Имеет динамическое содержимое, я использую автоматическую разметку, чтобы изменить его размер, и это супервид У меня все отлично меняется, за исключением tableHeaderView, который находится прямо под Paralax Table View в hiearchy.
Я нашел единственный способ изменить размер этого заголовка программно со следующим кодом:
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 есть несколько постов по этому поводу, но ни один из них не ясен и закончил тем, что запутал меня больше Вот несколько из них:
Автоматическая разметка на UITableViewHeader
Автоматическая разметка для tableHeaderView
Можно ли использовать AutoLayout с tableHeaderView UITableView?
В действительности нет смысла менять свойство 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: Как уже отмечали другие, решение, опубликованное в Edit 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;
}