6

自動レイアウトを UITableView に追加する方法について明確な答えを探していました。これまでのところ、私のコードは次のようになります。

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
    UINib *nib = [UINib nibWithNibName:@"HomeHeaderView" bundle:nil];
    UIView *headerView = (UIView *)[nib instantiateWithOwner:self options:nil][0];
    [headerView.layer setCornerRadius:6.0];
    [headerView setTranslatesAutoresizingMaskIntoConstraints:NO];

//    NSDictionary *viewsDictionary = NSDictionaryOfVariableBindings(headerView);
//    NSMutableArray *headerConstraints = [[NSMutableArray alloc] init];
//    [headerConstraints addObject:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[headerView]-|" options:0 metrics:nil views:viewsDictionary]];
//        [headerConstraints addObject:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-[headerView]-|" options:0 metrics:nil views:viewsDictionary]];
//    [self.actionsTableView addConstraints:headerConstraints];
//    [self.view addSubview:headerView];
    tableView.tableHeaderView = headerView;
    [headerView layoutSubviews];

    NSLayoutConstraint *centerX = [NSLayoutConstraint constraintWithItem:headerView attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeCenterX multiplier:1 constant:0];
    NSLayoutConstraint *centerY = [NSLayoutConstraint constraintWithItem:headerView attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeCenterY multiplier:1 constant:0];
    NSLayoutConstraint *width = [NSLayoutConstraint constraintWithItem:headerView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:0 multiplier:1 constant:300];
    NSLayoutConstraint *height = [NSLayoutConstraint constraintWithItem:headerView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:0 multiplier:1 constant:90];
    [self.view addConstraints:@[centerX, centerY, width, height]];

    return headerView;
}

基本的に、ヘッダー ビュー用の nib ファイルがあり、その nib を UITableViewHeader の中央に配置したいと考えています。縦向きと横向きに応じて拡大縮小したいと思います。制約を適切に設定したかどうかは正直わかりません。toItemビューコントローラーのビューなのか、それともテーブルビュー自体なのかわかりませんでした 。

また、ヘッダービューをビューコントローラーのビューまたはテーブルビュー自体のサブビューとして追加する必要があるかどうかもわかりませんでした。

または、 tableView.tableHeaderView = headerView を設定するだけで十分かどうかわかりませんでした。

このようなことのベストプラクティスが何であるかは本当にわかりません。それがすべてIBでもできるかどうかはわかりませんでした。現在、表示されているコードでは、次のエラーが発生します。

'Auto Layout still required after executing -layoutSubviews. UITableView's implementation of -layoutSubviews needs to call super.'

私が追加したのはそのエラーのためです[headerView layoutSubviews]

これについての考えは?前もって感謝します!

4

3 に答える 3

3

これはきちんとした解決策です:

オプション: initWithStyle:UITableViewStyleGrouped で tableViewHeader のフローティングを防止

2 つのプロパティを作成します。ラベルはデモンストレーション用です。

@property (nonatomic, strong, readwrite) UIView *headerView;
@property (nonatomic, strong, readwrite) UILabel *headerLabel;

viewDidLoad ですべてをセットアップします。

self.headerView = [[UIView alloc] initWithFrame:CGRectZero];
self.headerLabel = [[UILabel alloc] init];
self.headerLabel.text = @"Test";
self.headerLabel.numberOfLines = 0; //unlimited
self.headerLabel.textAlignment = NSTextAlignmentCenter;
self.headerLabel.translatesAutoresizingMaskIntoConstraints = NO; //always set this to NO when using AutoLayout
[self.headerView addSubview:self.headerLabel];

NSString *horizontalFormat = @"H:|-[headerLabel]-|";
NSArray *horizontalConstraints = [NSLayoutConstraint constraintsWithVisualFormat:horizontalFormat options:0 metrics:nil views:@{@"headerLabel":self.headerLabel}];
[self.headerView addConstraints:horizontalConstraints];

NSString *verticalFormat = @"V:|-[headerLabel]-|";
NSArray *verticalConstraints = [NSLayoutConstraint constraintsWithVisualFormat:verticalFormat options:0 metrics:nil views:@{@"headerLabel":self.headerLabel}];
[self.headerView addConstraints:verticalConstraints];

viewForHeaderInSection では:

return self.headerView;

heightForHeaderInSection:

self.headerLabel.preferredMaxLayoutWidth = tableView.bounds.size.width;
return [self.headerView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height;
于 2015-09-14T12:04:18.523 に答える
3

本当の問題はviewForHeaderInSection:、テーブルのheaderView. それらは無関係です。

前者はセクションのヘッダーです。デリゲート メソッドからビューを返します。

後者はテーブルのヘッダーです。ビューを設定します。おそらくviewDidLoad.

制約は通常の方法で機能します。ただし、それらはサブビューに対する内部制約のみであるべきです。ビューを作成した時点では、ビューはインターフェースにありません。そして、そのサイズと場所はその時点ではあなた次第ではありません。セクション ヘッダーの場合は、正しく収まるように自動的にサイズ変更されます (テーブルの幅と、テーブルまたはデリゲートのヘッダーの高さに関するステートメントに従って)。テーブル ヘッダーの場合は、絶対的な高さを指定できますが、幅は正しく収まるようにサイズ変更されます。

以下は、サブビューに対する内部制約を使用してセクション ヘッダーを構築する完全な例です。

- (UIView *)tableView:(UITableView *)tableView 
        viewForHeaderInSection:(NSInteger)section {
    UITableViewHeaderFooterView* h =
        [tableView dequeueReusableHeaderFooterViewWithIdentifier:@"Header"];
    if (![h.tintColor isEqual: [UIColor redColor]]) {
        h.tintColor = [UIColor redColor];
        h.backgroundView = [UIView new];
        h.backgroundView.backgroundColor = [UIColor blackColor];
        UILabel* lab = [UILabel new];
        lab.tag = 1;
        lab.font = [UIFont fontWithName:@"Georgia-Bold" size:22];
        lab.textColor = [UIColor greenColor];
        lab.backgroundColor = [UIColor clearColor];
        [h.contentView addSubview:lab];
        UIImageView* v = [UIImageView new];
        v.tag = 2;
        v.backgroundColor = [UIColor blackColor];
        v.image = [UIImage imageNamed:@"us_flag_small.gif"];
        [h.contentView addSubview:v];
        lab.translatesAutoresizingMaskIntoConstraints = NO;
        v.translatesAutoresizingMaskIntoConstraints = NO;
        [h.contentView addConstraints:
         [NSLayoutConstraint 
          constraintsWithVisualFormat:@"H:|-5-[lab(25)]-10-[v(40)]"
          options:0 metrics:nil views:@{@"v":v, @"lab":lab}]];
        [h.contentView addConstraints:
         [NSLayoutConstraint 
          constraintsWithVisualFormat:@"V:|[v]|"
           options:0 metrics:nil views:@{@"v":v}]];
        [h.contentView addConstraints:
         [NSLayoutConstraint
          constraintsWithVisualFormat:@"V:|[lab]|"
           options:0 metrics:nil views:@{@"lab":lab}]];
    }
    UILabel* lab = (UILabel*)[h.contentView viewWithTag:1];
    lab.text = self.sectionNames[section];
    return h;
}
于 2013-09-17T20:09:27.337 に答える
3

カスタムビューと制約を に追加しているため、マットによって提供されたソリューションは完璧ではない可能性があることがUITableViewHeaderFooterViewわかりましたcontentView。これにより、実行時に常に自動レイアウト警告が発生しますUnable to simultaneously satisfy constraints。動的なヘッダーの高さが必要な場合です。

contentView理由はわかりませんが、iOSがそのビューの固定幅と高さを設定するためにいくつかの追加の制約を追加していると推測できます。実行時に生成された警告は、手動で追加した制約がそれらで満足できないことを示しています。これは、サブビューが収まるように制約がヘッダー ビューを拡大する必要があるため明らかです。

解決策は非常に簡単です。 を使用せずUITableViewHeaderFooterViewcontentViewサブビューを に直接追加するだけUITableViewHeaderFooterViewです。iOS 8.1で問題なく動作することを確認できました。複数のビューを追加してヘッダーの背景色を変更する場合は、UIViewヘッダー ビューを塗りつぶす (AutoLayout 制約のおかげで) 追加することを検討してから、そのビューに必要なすべてのサブビューを追加することを検討してください (私はそれを呼び出していますcustomContentView)。こうすることで、AutoLayout の問題を回避し、ヘッダーのサイズを自動調整することができますUITableView

于 2014-12-03T20:42:13.797 に答える