Jak ustawić wysokość tableHeaderView (UITableView) z autolayout?

Przez ostatnie 3 lub 4 godziny uderzałem głową o ścianę i nie mogę tego zrozumieć. Mam UIViewController z pełnym ekranem UITableView wewnątrz niego (jest kilka innych rzeczy na ekranie, dlatego nie mogę użyć UITableViewController) i chcę, aby mój tableHeaderView zmienił rozmiar z autolayout. Nie trzeba dodawać, że nie współpracuje.

Zobacz zrzut ekranu poniżej.

Ponieważ opisowa etykieta (np. Tekst „Przegląd informacji o liście tutaj.”) Ma treść dynamiczną, używam opcji autoukładu, aby zmienić jego rozmiar i jego podgląd. Zmieniłem ładnie wszystko, z wyjątkiem tabeli tableHeaderView, która znajduje się tuż pod widokiem tabeli Paralax w hierarchii.

Jedynym sposobem na zmianę rozmiaru nagłówka jest programowo z następującym kodem:

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

W tym przypadku headerFrameHeight jest ręcznym obliczeniem wysokości tableViewHeader w następujący sposób(innerHeaderView to biały obszar lub drugi „Widok”, headerView to 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);

Kalkulacja ręczna działa, ale jest niezdarna i podatna na błędy, jeśli sytuacja zmieni się w przyszłości. Chcę mieć możliwość automatycznej zmiany rozmiaru tableHeaderView na podstawie podanych ograniczeń, tak jak w dowolnym innym miejscu. Ale dla mnie nie mogę tego zrozumieć.

Jest kilka postów na temat SO w tej sprawie, ale żadne nie jest jasne i skończyło się na tym, że bardziej mnie pomyliłem. Oto kilka:

Auto układ na UITableViewHeader

Układ automatyczny dla tableHeaderView

Czy możliwe jest użycie funkcji AutoLayout przy użyciu funkcji tableHeaderView UITableView?

wysokość widoku nagłówka tabeli jest nieprawidłowa, gdy używany jest układ automatyczny, IB i rozmiary czcionek

Nie ma sensu zmieniać właściwości translatesAutoresizingMaskIntoConstraints na NO, ponieważ powoduje to dla mnie błędy i i tak nie ma sensu.

Każda pomoc byłaby naprawdę mile widziana!

EDYTUJ 1: Dzięki sugestii TomSwift udało mi się to zrozumieć. Zamiast ręcznie obliczać wysokość przeglądu, mogę go obliczyć dla mnie w następujący sposób, a następnie ponownie ustawić tableHeaderView jak poprzednio.

[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];

Edytuj 2: Jak zauważyli inni, rozwiązanie opublikowane w Edit 1 wydaje się nie działać w viewDidLoad. Wydaje się jednak, że działa w viewWillLayoutSubviews. Przykładowy kod poniżej:

// 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;
}

questionAnswers(9)

yourAnswerToTheQuestion