为什么表头视图中的这些约束不明确?

我有一个“tableHeaderView”,这是一个UIView . 它包含一个UIImageView,其高度设置为200:

let tableView: UITableView = .init(frame: .zero)
tableView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(tableView)

let tableHeaderView: UIView = .init(frame: .zero)
tableHeaderView.translatesAutoresizingMaskIntoConstraints = false

let imageView: UIImageView = .init(frame: .zero)
imageView.translatesAutoresizingMaskIntoConstraints = false
tableHeaderView.addSubview(imageView)

tableView.tableHeaderView = tableHeaderView

var constraints: [NSLayoutConstraint] = []

// Set imageView's leading and trailing to tableHeaderView's leading and trailing
constraints += NSLayoutConstraint.constraints(
    withVisualFormat: "H:|-0-[imageView]-0-|",
    options: [],
    metrics: nil,
    views: ["imageView": imageView]
)

// Set imageView's top and bottom to tableHeaderView's top and bottom
// Also, set imageView's height to 200
constraints += NSLayoutConstraint.constraints(
    withVisualFormat: "V:|-0-[imageView(200)]-0|",
    options: [],
    metrics: nil,
    views: ["imageView": imageView]
)

// Set tableHeaderView's width to tableView's width
constraints.append(
    NSLayoutConstraint.init(
        item: tableHeaderView,
        attribute: .width,
        relatedBy: .equal,
        toItem: tableView,
        attribute: .width,
        multiplier: 1,
        constant: 0
    )
)

// Set tableView's leading and trailing to view's leading and trailing
constraints += NSLayoutConstraint.constraints(
    withVisualFormat: "H:|-0-[tableView]-0-|",
    options: [],
    metrics: nil,
    views: ["tableView": tableView]
)

// Set tableView's top and bottom to view's top and bottom
constraints += NSLayoutConstraint.constraints(
    withVisualFormat: "V:|-0-[tableView]-0-|",
    options: [],
    metrics: nil,
    views: ["tableView": tableView]
)

NSLayoutConstraint.activate(constraints)

这些约束给了我这个结果:

enter image description here

您可以看到 Headers 视图覆盖了几个单元格 . 当我使用UI调试器时,这就是我得到的:

enter image description here

它告诉我tableHeaderView的约束是不明确的,但是,控制台中没有打印警告消息 . 我该如何解决这个问题?

回答(2)

2 years ago

这是Objective c代码,通过这个你可以得到什么是错误的想法 .

  • Tableview约束应该与self.view一起使用

  • Headers 约束应与您的tableview一起使用

  • 在self.view中添加最终约束

我刚刚为Objective c创建了示例类,对swift来说无关紧要,只需比较一下逻辑 .

#import "ViewController.h"

@implementation ViewController

@synthesize tableview;
- (void)viewDidLoad {
    [super viewDidLoad];
}

- (void)viewWillLayoutSubviews {
[super viewWillLayoutSubviews];

NSLayoutConstraint *leftconstraint = [NSLayoutConstraint
                                      constraintWithItem:self.tableview
                                      attribute:NSLayoutAttributeLeft
                                      relatedBy:NSLayoutRelationEqual
                                      toItem:self.view
                                      attribute:NSLayoutAttributeLeft
                                      multiplier:1.0
                                      constant:0.0];
leftconstraint.active = YES;

NSLayoutConstraint *rightconstraint = [NSLayoutConstraint
                                       constraintWithItem:self.tableview
                                       attribute:NSLayoutAttributeRight
                                       relatedBy:NSLayoutRelationEqual
                                       toItem:self.view
                                       attribute:NSLayoutAttributeRight
                                       multiplier:1.0
                                       constant:0.0];
rightconstraint.active = YES;

NSLayoutConstraint *topconstraint = [NSLayoutConstraint
                                     constraintWithItem:self.tableview
                                     attribute:NSLayoutAttributeTop
                                     relatedBy:NSLayoutRelationEqual
                                     toItem:self.view
                                     attribute:NSLayoutAttributeTop
                                     multiplier:1.0
                                     constant:0.0];
topconstraint.active = YES;

NSLayoutConstraint *bottomconstraint = [NSLayoutConstraint
                                        constraintWithItem:self.tableview
                                        attribute:NSLayoutAttributeBottom
                                        relatedBy:NSLayoutRelationEqual
                                        toItem:self.view
                                        attribute:NSLayoutAttributeBottom
                                        multiplier:1.0
                                        constant:0.0];
bottomconstraint.active = YES;

[self.view addConstraints:@[leftconstraint, rightconstraint, topconstraint, bottomconstraint]];

// header view constraint

NSLayoutConstraint *left = [NSLayoutConstraint
                            constraintWithItem:headeerView
                            attribute:NSLayoutAttributeLeft
                            relatedBy:NSLayoutRelationEqual
                            toItem:self.tableview
                            attribute:NSLayoutAttributeLeft
                            multiplier:1.0
                            constant:0.0];
left.active = YES;


NSLayoutConstraint *right = [NSLayoutConstraint
                            constraintWithItem:headeerView
                            attribute:NSLayoutAttributeRight
                            relatedBy:NSLayoutRelationEqual
                            toItem:self.tableview
                            attribute:NSLayoutAttributeRight
                            multiplier:1.0
                            constant:0.0];
right.active = YES;

NSLayoutConstraint *top = [NSLayoutConstraint
                             constraintWithItem:headeerView
                             attribute:NSLayoutAttributeTop
                             relatedBy:NSLayoutRelationEqual
                             toItem:self.tableview
                             attribute:NSLayoutAttributeTop
                             multiplier:1.0
                             constant:0.0];
top.active = YES;

NSLayoutConstraint *width = [NSLayoutConstraint
                           constraintWithItem:headeerView
                           attribute:NSLayoutAttributeWidth
                           relatedBy:NSLayoutRelationEqual
                           toItem:self.tableview
                           attribute:NSLayoutAttributeWidth
                           multiplier:1.0
                           constant:0.0];
width.active = YES;

[self.view addConstraints: @[left,right,top,width]];

}

- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];

[self.view setTranslatesAutoresizingMaskIntoConstraints:NO];



self.tableview = [[UITableView alloc] initWithFrame: CGRectZero style:UITableViewStyleGrouped];
self.tableview.delegate=self;
self.tableview.dataSource=self;

[self.tableview setTranslatesAutoresizingMaskIntoConstraints:NO];

UIImage *img = [[UIImage alloc] init];
img = [UIImage imageNamed:@"header.png"];

headeerView = [[UIImageView alloc] initWithImage:img];
[headeerView setTranslatesAutoresizingMaskIntoConstraints:NO];

self.tableview.tableHeaderView = headeerView;

[self.view addSubview:self.tableview];

}

- (nonnull UITableViewCell *)tableView:(nonnull UITableView *)tableView cellForRowAtIndexPath:(nonnull NSIndexPath *)indexPath {

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"tableviewcell"];
if (cell == nil)
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"tableviewcell"];

return cell;
}

- (NSInteger)tableView:(nonnull UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 5;
}


@end

enter image description here

2 years ago

UITableView应该为您管理 Headers 的布局,因此您只需要设置容器视图的高度(在您的情况下为tableHeaderView)并根据您的需要添加/布局其子视图 . 为什么不尝试这个,看看它是否有效:

let tableHeaderView = UIView(frame: CGRect(origin: CGPoint(),
                                     size: CGSize(width: 0, height: someHeightConstant)) )
    let imageView = UIImageView(frame: .zero)

    tableHeaderView.addSubview(imageView)
    //now you should set constraints on the imageview (omitting the code for readability)

    tableView.tableHeaderView = tableHeaderView

如果您需要,在用户滚动时覆盖单元格的 Headers ,请考虑使用节 Headers . 希望这有帮助,我正确理解你的问题 .