Rozbijam się tym głową o ścianę przez ostatnie 3 lub 4 godziny i nie mogę tego rozgryźć. Mam UIViewController z pełnoekranowym UITableView wewnątrz niego (na ekranie jest kilka innych rzeczy, dlatego nie mogę użyć UITableViewController) i chcę, aby moja tableHeaderView zmieniła rozmiar za pomocą autolayout. Nie trzeba dodawać, że nie współpracuje.
Zobacz zrzut ekranu poniżej.
Ponieważ OverviewLabel (np. Tekst „List Overview information here”) ma dynamiczną zawartość, używam autolayout, aby zmienić jego rozmiar i jego superview. Mam wszystko ładnie zmieniające rozmiar, z wyjątkiem tableHeaderView, który znajduje się tuż poniżej widoku tabeli Paralax w hierarchii.
Jedynym sposobem, w jaki udało mi się zmienić rozmiar tego widoku nagłówka, jest programowe użycie następującego kodu:
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 „View”, 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);
Ręczne obliczanie działa, ale jest niezgrabne i podatne na błędy, jeśli coś się zmieni w przyszłości. Chcę mieć możliwość automatycznej zmiany rozmiaru tableHeaderView na podstawie podanych ograniczeń, tak jak w każdym innym miejscu. Ale na całe życie nie mogę tego rozgryźć.
Jest kilka postów na SO na ten temat, ale żaden nie jest jasny i ostatecznie bardziej mnie zdezorientował. Oto kilka:
Naprawdę nie ma sensu zmieniać właściwości translatesAutoresizingMaskIntoConstraints na NO, ponieważ powoduje to po prostu błędy i nie ma sensu koncepcyjnego.
Każda pomoc byłaby naprawdę doceniona!
EDYCJA 1: Dzięki sugestii TomSwift udało mi się to rozgryźć. 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];
Edycja 2: Jak zauważyli inni, rozwiązanie opublikowane w Edit 1 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;
}
setTableHeaderView
nie działa na Xcode6. Problem polega na tym, że na komórki nakłada się tableHeaderView. Jednak działa na Xcode5