具有自动布局约束的 UITableViewCell 子类大小不正确

Posted

技术标签:

【中文标题】具有自动布局约束的 UITableViewCell 子类大小不正确【英文标题】:UITableViewCell subclass with Auto Layout constraints incorrectly sized 【发布时间】:2015-02-07 23:39:55 【问题描述】:

我正在尝试以编程方式创建一个自定义 UITableViewCell,没有 XIB,它由一个使用自动布局指定单元格高度的 UILabel 组成。我已经为单元格的contentView 提供了这个标签的前导、尾随、顶部和底部约束,但这些约束不会影响表格视图单元格的高度。标签全部堆叠在一起,没有填充,表格视图分隔线也不与标签对齐。这里有什么问题?

自定义单元格:

@interface TransactionTableViewCell ()

@property (nonatomic, assign) BOOL didUpdateConstraints;

@end


@implementation TransactionTableViewCell

- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier 

    if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) 
        self.translatesAutoresizingMaskIntoConstraints = NO;

        self.transactionPriceLabel = [[UILabel alloc] init];
        self.transactionPriceLabel.backgroundColor = [UIColor yellowColor];
        self.transactionPriceLabel.translatesAutoresizingMaskIntoConstraints = NO;
        [self.contentView addSubview:self.transactionPriceLabel];
    

    [self setNeedsUpdateConstraints]; //had to add this otherwise updateConstraints isn't called for some reason

    return self;



- (void)updateConstraints 
    if (!self.didUpdateConstraints) 
        self.didUpdateConstraints = YES;

        [self.contentView addConstraint:[NSLayoutConstraint constraintWithItem:self.transactionPriceLabel
                                                                     attribute:NSLayoutAttributeTrailing
                                                                     relatedBy:NSLayoutRelationEqual
                                                                        toItem:self.contentView
                                                                     attribute:NSLayoutAttributeTrailing
                                                                    multiplier:1
                                                                      constant:-15]];
        [self.contentView addConstraint:[NSLayoutConstraint constraintWithItem:self.transactionPriceLabel
                                                                     attribute:NSLayoutAttributeTop
                                                                     relatedBy:NSLayoutRelationEqual
                                                                        toItem:self.contentView
                                                                     attribute:NSLayoutAttributeTop
                                                                    multiplier:1
                                                                      constant:15]];
        [self.contentView addConstraint:[NSLayoutConstraint constraintWithItem:self.transactionPriceLabel
                                                                     attribute:NSLayoutAttributeBottom
                                                                     relatedBy:NSLayoutRelationEqual
                                                                        toItem:self.contentView
                                                                     attribute:NSLayoutAttributeBottom
                                                                    multiplier:1
                                                                      constant:15]];
        [self.contentView addConstraint:[NSLayoutConstraint constraintWithItem:self.transactionPriceLabel
                                                                     attribute:NSLayoutAttributeLeading
                                                                     relatedBy:NSLayoutRelationEqual
                                                                        toItem:self.contentView
                                                                     attribute:NSLayoutAttributeLeading
                                                                    multiplier:1
                                                                      constant:15]];
    

    [super updateConstraints];

视图控制器:

- (void)viewDidLoad 
    UITableView *tableView = [[UITableView alloc] initWithFrame:self.view.bounds];
    tableView.dataSource = self;
    tableView.delegate = self;
    tableView.rowHeight = UITableViewAutomaticDimension;
    tableView.estimatedRowHeight = 44.0;
    [self.view addSubview:tableView];

    tableView.translatesAutoresizingMaskIntoConstraints = NO;
    [self.view addConstraint:[NSLayoutConstraint constraintWithItem:tableView
                                                     attribute:NSLayoutAttributeLeading
                                                     relatedBy:NSLayoutRelationEqual
                                                        toItem:self.view
                                                     attribute:NSLayoutAttributeLeading
                                                    multiplier:1
                                                      constant:0]];
    [self.view addConstraint:[NSLayoutConstraint constraintWithItem:tableView
                                                     attribute:NSLayoutAttributeTop
                                                     relatedBy:NSLayoutRelationEqual
                                                        toItem:self.view
                                                     attribute:NSLayoutAttributeTop
                                                    multiplier:1
                                                      constant:0]];
    [self.view addConstraint:[NSLayoutConstraint constraintWithItem:tableView
                                                     attribute:NSLayoutAttributeBottom
                                                     relatedBy:NSLayoutRelationEqual
                                                        toItem:self.view
                                                     attribute:NSLayoutAttributeBottom
                                                    multiplier:1
                                                      constant:0]];
    [self.view addConstraint:[NSLayoutConstraint constraintWithItem:tableView
                                                     attribute:NSLayoutAttributeTrailingMargin
                                                     relatedBy:NSLayoutRelationEqual
                                                        toItem:self.view
                                                     attribute:NSLayoutAttributeTrailingMargin
                                                    multiplier:1
                                                      constant:0]];

    [tableView registerClass:[TransactionTableViewCell class] forCellReuseIdentifier:@"cell"];


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
    return 10;


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
    TransactionTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell" forIndexPath:indexPath];

    cell.transactionPriceLabel.text = @"label text";
    cell.transactionPriceLabel.textColor = [UIColor redColor];

    return cell;

【问题讨论】:

【参考方案1】:

标签底部到 contentView 约束底部的常量应该是 -15,而不是 15。

【讨论】:

好眼光!哇,就是这么简单。

以上是关于具有自动布局约束的 UITableViewCell 子类大小不正确的主要内容,如果未能解决你的问题,请参考以下文章

是啥导致两个具有相同自动布局约束的 UITableViewCell 表现不同?

在具有自动布局的 UITableViewCell 中动态调整大小的 UIWebView - 违反约束

自动布局 UITableViewCell

缩进 UITableViewCell 中的所有自动布局约束

UITableViewCell中的自动布局约束不匹配

UITableViewCell为啥会有自动布局约束冲突