Я бился головой об стену этим последние 3 или 4 часа и, кажется, не могу этого понять. У меня есть UIViewController с полноэкранным UITableView внутри него (на экране есть кое-что другое, поэтому я не могу использовать UITableViewController), и я хочу, чтобы мой tableHeaderView изменял размер с помощью автозапуска. Излишне говорить, что это не сотрудничество.
Смотрите скриншот ниже.
Поскольку overviewLabel (например, текст «Список обзорной информации здесь.») Имеет динамическое содержимое, я использую автоматическое размещение, чтобы изменить его размер и его супервизор. У меня все красиво меняется, за исключением tableHeaderView, который находится прямо под представлением таблицы Paralax в иерархии.
Я нашел единственный способ изменить размер этого заголовка - программно, с помощью следующего кода:
CGRect headerFrame = self.headerView.frame;
headerFrame.size.height = headerFrameHeight;
self.headerView.frame = headerFrame;
[self.listTableView setTableHeaderView:self.headerView];
В этом случае headerFrameHeight - это ручной расчет высоты tableViewHeader следующим образом (innerHeaderView - это белая область или второе «представление», 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: Как отмечали другие, решение, опубликованное в 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;
}
setTableHeaderView
не работает на Xcode6. Проблема в том, что ячейки перекрываются tableHeaderView. Однако он работает на Xcode5