使用锚以编程方式设置 UITableViewCell 的布局

Posted

技术标签:

【中文标题】使用锚以编程方式设置 UITableViewCell 的布局【英文标题】:Setting UITableViewCell's layout programmatically using anchors 【发布时间】:2018-06-22 08:41:59 【问题描述】:

我正在尝试使用自动布局的锚点创建自定义 UITableViewCell。单元格应:

有两列 有三行 “单元格”的内容应该只是 UILabel 应根据行高动态设置高度

然而,UIViewCell 的布局锚似乎与 UIView 的工作方式不同,我现在得到了我想要的结果,我猜这可能是由于 UITableView 的复杂视图层次结构(内容视图、附件视图......)。

我在这里犯了一些明显的错误吗?将 UILabel 包装到 UIView 或 UIStackView 中会解决问题吗?

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier 
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self) 

        UILabel *col1row1 = [UILabel new];
        UILabel *col1row2 = [UILabel new];
        UILabel *col1row3 = [UILabel new];
        UILabel *col2row1 = [UILabel new];
        UILabel *col2row2 = [UILabel new];
        UILabel *col2row3 = [UILabel new];

        [self setTranslatesAutoresizingMaskIntoConstraints:NO];
        [self.contentView setTranslatesAutoresizingMaskIntoConstraints:NO];
        [col1row1 setTranslatesAutoresizingMaskIntoConstraints:NO];
        [col1row2 setTranslatesAutoresizingMaskIntoConstraints:NO];
        [col1row3 setTranslatesAutoresizingMaskIntoConstraints:NO];
        [col2row1 setTranslatesAutoresizingMaskIntoConstraints:NO];
        [col2row2 setTranslatesAutoresizingMaskIntoConstraints:NO];
        [col2row3 setTranslatesAutoresizingMaskIntoConstraints:NO];

        self.col1row1 = col1row1;
        self.col1row2 = col1row2;
        self.col1row3 = col1row3;
        self.col2row1 = col2row1;
        self.col2row2 = col2row2;
        self.col2row3 = col2row3;

        [self.contentView addSubview:col1row1];
        [self.contentView addSubview:col1row2];
        [self.contentView addSubview:col1row3];
        [self.contentView addSubview:col2row1];
        [self.contentView addSubview:col2row2];
        [self.contentView addSubview:col2row3];

        [col1row1 setTextAlignment:NSTextAlignmentLeft];
        [col1row2 setTextAlignment:NSTextAlignmentLeft];
        [col1row3 setTextAlignment:NSTextAlignmentLeft];
        [col2row1 setTextAlignment:NSTextAlignmentRight];
        [col2row2 setTextAlignment:NSTextAlignmentRight];
        [col2row3 setTextAlignment:NSTextAlignmentRight];

        [col1row1 setBackgroundColor:[UIColor yellowColor]];
        [col1row2 setBackgroundColor:[UIColor yellowColor]];
        [col1row3 setBackgroundColor:[UIColor yellowColor]];
        [col2row1 setBackgroundColor:[UIColor yellowColor]];
        [col2row2 setBackgroundColor:[UIColor yellowColor]];
        [col2row3 setBackgroundColor:[UIColor yellowColor]];

        [self.widthAnchor constraintEqualToAnchor:self.superview.widthAnchor multiplier:1.0].active = YES;
        [self.contentView.widthAnchor constraintEqualToAnchor:self.superview.widthAnchor multiplier:1.0].active = YES;

        [col1row1.leftAnchor constraintEqualToAnchor:self.contentView.leftAnchor constant:1.0].active = YES;
        [col1row2.leftAnchor constraintEqualToAnchor:self.contentView.leftAnchor constant:1.0].active = YES;
        [col1row3.leftAnchor constraintEqualToAnchor:self.contentView.leftAnchor constant:1.0].active = YES;
        [col2row1.rightAnchor constraintEqualToAnchor:self.contentView.rightAnchor constant:1.0].active = YES;
        [col2row2.rightAnchor constraintEqualToAnchor:self.contentView.rightAnchor constant:1.0].active = YES;
        [col2row3.rightAnchor constraintEqualToAnchor:self.contentView.rightAnchor constant:1.0].active = YES;

        [col1row1.topAnchor constraintEqualToAnchor:self.contentView.topAnchor constant:1.0].active = YES;
        [col1row2.topAnchor constraintEqualToAnchor:col1row1.bottomAnchor constant:1.0].active = YES;
        [col1row3.topAnchor constraintEqualToAnchor:col1row2.bottomAnchor constant:1.0].active = YES;
        [col2row1.topAnchor constraintEqualToAnchor:self.contentView.topAnchor constant:1.0].active = YES;
        [col2row2.topAnchor constraintEqualToAnchor:col2row1.bottomAnchor constant:1.0].active = YES;
        [col2row3.topAnchor constraintEqualToAnchor:col2row2.bottomAnchor constant:1.0].active = YES;

        [self.bottomAnchor constraintEqualToAnchor:col1row3.bottomAnchor constant:1.0].active = YES;
        [self.contentView.bottomAnchor constraintEqualToAnchor:col1row3.bottomAnchor constant:1.0].active = YES;

        [self.contentView setBackgroundColor:[UIColor greenColor]];

    
    return self;

删除@Mahendra GP 建议的行后

[self setTranslatesAutoresizingMaskIntoConstraints:NO];
[self.contentView setTranslatesAutoresizingMaskIntoConstraints:NO];
[self.widthAnchor constraintEqualToAnchor:self.superview.widthAnchor multiplier:1.0].active = YES;
[self.contentView.widthAnchor constraintEqualToAnchor:self.superview.widthAnchor multiplier:1.0].active = YES;

...结果看起来更好,但第 2 列在视图层次结构中不可见:

【问题讨论】:

您无法使用自动布局来布局单元格和内容视图。表格视图会为您做到这一点。删除您在单元格或内容视图上添加约束的行 - 在任何情况下,此时超级视图将为零。 并使用视图层次结构调试器找出那些第 2 列标签的确切位置:) 您是想弄清楚如何使用锚点,还是只是为了解决这个特定的单元格布局问题?如果是后者,我建议使用堆栈视图。 @AshleyMills 想要两者兼得,了解问题并找到最佳解决方案。堆栈视图在将其锚定到表格视图单元格时可能会遇到类似的问题。 我的建议是使用情节提要中的堆栈视图来构建它,如果它按预期工作,请检查系统创建的约束 【参考方案1】:

对于表格视图单元格,您不需要设置以下...

[self setTranslatesAutoresizingMaskIntoConstraints:NO];
[self.contentView setTranslatesAutoresizingMaskIntoConstraints:NO];

只需要在要添加的视图上设置。

widthAnchor 也不需要单元格,因为表格视图单元格的宽度与表格视图一样。所以删除这些行...

[self.widthAnchor constraintEqualToAnchor:self.superview.widthAnchor multiplier:1.0].active = YES;
[self.contentView.widthAnchor constraintEqualToAnchor:self.superview.widthAnchor multiplier:1.0].active = YES;

编辑:

将第 2 列的rightAnchor 约束更改如下...

[self.contentView.rightAnchor constraintEqualToAnchor:col2row1.rightAnchor constant:1.0].active = YES;
[self.contentView.rightAnchor constraintEqualToAnchor:col2row2.rightAnchor constant:1.0].active = YES;
[self.contentView.rightAnchor constraintEqualToAnchor:col2row3.rightAnchor constant:1.0].active = YES;

【讨论】:

我用新的预览更新了问题,现在看起来更好了。 得到相同的结果。 我知道发生了什么,父 UITableViewController 太宽了。必须启用剪辑的内容才能显示。此行缺少[tableViewController.tableView setTranslatesAutoresizingMaskIntoConstraints:NO];

以上是关于使用锚以编程方式设置 UITableViewCell 的布局的主要内容,如果未能解决你的问题,请参考以下文章

偏移html锚以调整固定标题[重复]

如何设置特定UITableViewCell的背景颜色

为啥文本字段委托不能以编程方式在文本字段上使用设置文本?

以编程方式使用 UINavigationController 设置 RootViewController

以编程方式使用 UIPickerView 文本设置 UITextField 文本

如何以编程方式使用密码设置屏幕锁定?