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

时间:2018-12-04 03:24:54

标签: ios swift uitableview

我有一个“ 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

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

enter image description here

它告诉我tableHeaderView的约束是模棱两可的,但是,控制台中没有打印警告消息。我该如何解决这个问题?

2 个答案:

答案 0 :(得分:0)

这是Objective c代码,通过它您可以了解发生了什么错误。

  • Tableview约束应带有self.view
  • 标题约束应与您的表视图一起使用
  • 在self.view中添加最终约束

我刚刚为目标c创建了示例类,不要急于求同,只需比较一下逻辑即可。

#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

答案 1 :(得分:0)

UITableView应该为您管理标题的布局,因此您只需要设置容器视图的高度(在您的情况下为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

如果需要,可以在用户滚动时在单元格上方覆盖标题,请考虑改用节标题。希望这会有所帮助,我会正确理解您的问题。