UiTableViewのヘッダービューを作成しようとしています(セクションヘッダーではなく、既にあります)。インターフェイスビルダーでXIBを設定しました。すべての接続が接続され、美しく動作します...テーブルが十分なスペースを与えていないことを除いて!私の問題は、テーブルの上部がテーブルのヘッダーと少し重なっていることです。
私のXIBは、すべてのボタンに対してautlayoutを使用してセットアップされており、IBは制約が競合/あいまいにならないことに満足しています。ビューはフリーフォームサイズに設定されますが、私の場合は320 x 471になります。その後、ビューの制約で、同じビューの固有のサイズを設定します。
今、これは私のテーブルで完璧に動作します。すべてが素晴らしく見えます。しかし、ヘッダービューのフォントをコードで手動で変更すると、レイアウトによってビューが大きくなり、テーブルの下に表示されます。
フォントとサイズを設定した後に、tableviewcontrollerにヘッダービューのための十分なスペースを確保する方法はありますか?これを説明するのが理にかなったことを願っています。
注:A Swift 3+バージョンはここにあります: https://Gist.github.com/marcoarment/1105553afba6b4900c10#gistcomment-1933639
アイデアは、systemLayoutSizeFittingSize:targetSize
を使用してヘッダーの高さを計算することです。
保持している制約を満たすビューのサイズを返します。保持するすべての制約とそのサブビューの制約を考慮して、ビューの最適なサイズを決定します。
ヘッダーの高さを変更した後、tableHeaderView
プロパティを再割り当てしてテーブルセルを調整する必要があります。
この答えに基づいて: 動的なセルレイアウトと可変行の高さのためのUITableViewでの自動レイアウトの使用
- (void)sizeHeaderToFit
{
UIView *header = self.tableView.tableHeaderView;
[header setNeedsLayout];
[header layoutIfNeeded];
CGFloat height = [header systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height;
CGRect frame = header.frame;
frame.size.height = height;
header.frame = frame;
self.tableView.tableHeaderView = header;
}
インターフェイスビルダーを使用して自動レイアウトで定義したカスタムビューにテーブルビューヘッダーを設定しようとしたときに、同様の問題が発生しました。
そうすると、セクションヘッダーによって隠されていることがわかります。
私の回避策は、「ダミービュー」をテーブルヘッダービューとして使用し、カスタムビューをサブビューとしてそのダミービューに追加することでした。これにより、自動レイアウトで、制約および包含ビューのフレームに従って外観を構成できると思います。これはおそらくvokilamのソリューションほどエレガントではありませんが、私には有効です。
CGRect headerFrame = CGRectMake(0, 0, yourWidth, yourHeight);
UIView *tempView = [[UIView alloc] initWithFrame:headerFrame];
[tempView setBackgroundColor:[UIColor clearColor]];
YourCustomView *customView = [[YourCustomView alloc] initWithFrame: headerFrame];
[tempView addSubview:movieHeader];
self.tableView.tableHeaderView = tempView;
tableHeaderView
は自動レイアウトでxib
から初期化されているため、カスタムheaderView
とsuperView
の制約は不明です。constraints
を追加する必要がありますカスタムheaderView
:
1.in viewDidLLoad
は、カスタムheaderViewをtableViewのtableHeaderViewに割り当てます
- (void)viewDidLoad
{
[super viewDidLoad];
UIView *yourHeaderView = [[[NSBundle mainBundle] loadNibNamed:@"yourHeaderView" owner:nil options:nil] objectAtIndex:0];
//important:turn off the translatesAutoresizingMaskIntoConstraints;Apple documents for details
yourHeaderView.translatesAutoresizingMaskIntoConstraints = NO;
self.tableView.tableHeaderView = yourHeaderView;
}
2.in void)updateViewConstraints、カスタムheaderViewの本質的な制約を追加
- (void)updateViewConstraints
{
NSDictionary *viewsDictionary = @{@"headerView":yourHeaderView};
NSArray *constraint_V = [NSLayoutConstraint constraintsWithVisualFormat:@"V:[headerView(121)]"
options:0
metrics:nil
views:viewsDictionary];
NSArray *constraint_H = [NSLayoutConstraint constraintsWithVisualFormat:@"H:[headerView(320)]"
options:0
metrics:nil
views:viewsDictionary];
[self.headerView addConstraints:constraint_H];
[self.headerView addConstraints:constraint_V];
NSArray *constraint_POS_V = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-0-[headerView]"
options:0
metrics:nil
views:viewsDictionary];
NSArray *constraint_POS_H = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-0-[headerView]"
options:0
metrics:nil
views:viewsDictionary];
[self.tableView addConstraints:constraint_POS_V];
[self.tableView addConstraints:constraint_POS_H];
[super updateViewConstraints];
}
OK! PS:関連ドキュメントは次のとおりです。---(View Controllerのビューのサイズ変更
私の問題を解決したのはこれでした:
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
sizeHeaderToFit()
}
private func sizeHeaderToFit() {
if let headerView = tableView.tableHeaderView {
headerView.setNeedsLayout()
headerView.layoutIfNeeded()
let height = headerView.systemLayoutSizeFittingSize(UILayoutFittingCompressedSize).height
var newFrame = headerView.frame
// Needed or we will stay in viewDidLayoutSubviews() forever
if height != newFrame.size.height {
newFrame.size.height = height
headerView.frame = newFrame
tableView.tableHeaderView = headerView
}
}
}
私はこの解決策をどこかで見つけて、魅力のように働いたが、どこにいるのか思い出せない。
私はvokilamの答えが素晴らしいと感じました。 Swiftでの彼のソリューションは次のとおりです。
func sizeHeaderToFit() {
guard let header = tableView.tableHeaderView else { return }
header.setNeedsLayout()
header.layoutIfNeeded()
let height = header.systemLayoutSizeFittingSize(UILayoutFittingCompressedSize).height
header.frame.size.height = height
tableView.tableHeaderView = header
}
他の答えは、tableHeaderViewを適切にサイズ変更するための正しい方向を示しました。ただし、ヘッダーとtableViewセルの間にギャップが生じていました。これにより、ヘッダーが拡大したか縮小したかによって、セルがヘッダーと重複する可能性もあります。
私はこれから行きました:
tableView.reloadData()
let height = tableViewHeader.systemLayoutSizeFitting(UILayoutFittingCompressedSize).height
tableView.tableHeaderView?.frame.size.height = height
ギャップ/オーバーラップを修正するには、tableView.reloadData()を前にではなく新しい高さを設定した後に移動するだけでした。
これに:
let height = tableViewHeader.systemLayoutSizeFitting(UILayoutFittingCompressedSize).height
tableView.tableHeaderView?.frame.size.height = height
tableView.reloadData()
@ SwiftArchitect、@ vokilam、および@mayqiyueによる回答を組み合わせ、ペン先の代わりにプログラムで作成されたtableHeaderView
を使用します(ただし、ペン先で動作しない理由はわかりません)。 iOS 10.x/Xcode 8.2.1で、ここに私が働いているものがあります:
View Controllerの-viewDidLoad
または-init
メソッド、またはTable Viewを使用している場所でビューを作成します。
MyCustomTableHeaderView *myCustomTableHeaderView = [[MyCustomTableHeaderView alloc] init]; // Don't set its frame
myCustomTableHeaderView.translatesAutoresizingMaskIntoConstraints = NO;
self.myTableView.tableHeaderView = myCustomTableHeaderView;
self.myCustomTableHeaderView = myCustomTableHeaderView; // We set and update our constraints in separate methods so we store the table header view in a UIView property to access it later
カスタムヘッダービューの制約を設定した場所( `updateConstraintsにある可能性がありますが、このメソッドは複数回呼び出すことができます):
// We use Pure Layout in our project, but the workflow is the same:
// Set width and height constraints on your custom view then pin it to the top and left of the table view
// Could also use VFL or NSLayoutConstraint methods
[self.myCustomTableHeaderView autoSetDimension:ALDimensionWidth toSize:CGRectGetWidth(self.superview.frame)]; // Width set to tableview's width
[self.myCustomTableHeaderView autoSetDimension:ALDimensionHeight toSize:height]; // Whatever you want your height to be
[self.myCustomTableHeaderView autoPinEdgeToSuperviewEdge:ALEdgeTop];
[self.myCustomTableHeaderView autoPinEdgeToSuperviewEdge:ALEdgeLeft];
// This is important
[self.myCustomTableHeaderView layoutIfNeeded]; // We didn't need to call -setNeedsLayout or reassign our custom header view to the table view's tableHeaderView property again, as was noted in other answers
私の場合、サブビューの1つがアスペクト比(幅と高さ)4:1制約を使用しているため、systemLayoutSizeFittingSize
は誤ったサイズを返します。
一定の高さの制約値(100)に変更すると、期待どおりに機能し始めます。
@vokilamによって提案されたsizeHeaderToFit
は私にとってはうまくいきませんでした。
動作したのは、viewDidLoad
の間に呼び出される@mayqiyueの修正バージョンで、配線された高さ、テーブルビューと同じ幅です。
// Anchor the headerview, and set width equal to superview
NSDictionary *viewsDictionary = @{@"headerView":self.tableView.tableHeaderView,
@"tableView":self.tableView};
[self.tableView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-0-[headerView]"
options:0
metrics:nil
views:viewsDictionary]];
[self.tableView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-0-[headerView]"
options:0
metrics:nil
views:viewsDictionary]];
[self.tableView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:[headerView(==tableView)]"
options:0
metrics:nil
views:viewsDictionary]];
[self.tableView.tableHeaderView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[headerView(121)]"
options:0
metrics:nil
views:viewsDictionary]];
@rmignecoの答えは私のために働いたので、ここにSwiftのバージョンがあります:
let headerFrame = CGRectMake(0, 0, 100, 1);
let tempView = UIView(frame: headerFrame);
tempView.backgroundColor = UIColor.clearColor()
let yourCustomView = CustomView(frame: headerFrame)
tempView.addSubview(yourCustomView)
self.tableView.tableHeaderView = tempView
以下のコードは私のために働いています:-これをUIViewクラスに追加してください-
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
self = [super initWithCoder:aDecoder];
if (self) {
self.frame = CGRectMake(0, 0, self.frame.size.width, [[self class] height]);
}
return self;
}