過去3、4時間、これで頭を壁にぶつけてきましたが、理解できないようです。フルスクリーンのUITableViewを内部に持つUIViewControllerがあり(画面上に他のものがあるため、UITableViewControllerを使用できません)、tableHeaderViewのサイズを自動レイアウトで変更したいと考えています。言うまでもなく、それは協力的ではありません。
以下のスクリーンショットを参照してください。
OverviewLabel(「ここに概要情報を一覧表示する」テキストなど)には動的コンテンツがあるため、自動レイアウトを使用してサイズを変更し、スーパービューにします。階層内の視差テーブルビューのすぐ下にあるtableHeaderViewを除いて、すべてのサイズを適切に変更できます。
そのヘッダービューのサイズを変更する唯一の方法は、次のコードを使用してプログラムで行うことです。
CGRect headerFrame = self.headerView.frame;
headerFrame.size.height = headerFrameHeight;
self.headerView.frame = headerFrame;
[self.listTableView setTableHeaderView:self.headerView];
この場合、headerFrameHeightは、次のようにtableViewHeaderの高さを手動で計算します(innerHeaderViewは白い領域、つまり2番目の「ビュー」です。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: トムスウィフトの提案のおかげで、私はそれを理解することができました。概要の高さを手動で計算する代わりに、次のように計算してから、以前のように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:他の人が指摘しているように、編集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