【问题标题】:Setting constraints on contentView edges breaks layout of UITableViewCell with masonry在 contentView 边缘上设置约束会破坏 UITableViewCell 的布局与砌体
【发布时间】:2016-06-10 04:38:52
【问题描述】:

我正在尝试创建一个表格视图单元格,左侧是图像,右侧是内容框。图片应该是正方形的,并且是单元格宽度的 20%,内容框(下面代码中的background)至少应该和图片一样大。最后,我想尊重 tableview 本身的布局边距。

除了最后一步,这很好,尊重表格视图的边距。设置这个会导致我的内容框在 tableview 很宽时设置过大或过小。

// Base class
    [self.background setContentCompressionResistancePriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisVertical];

    [self.background mas_makeConstraints:^(MASConstraintMaker *make) {
        make.leading.equalTo(self.contentView).with.offset(8.0).with.priorityMedium();
        make.trailing.equalTo(self.contentView).with.offset(-8.0).with.priorityMedium();
        make.top.equalTo(self.contentView).with.offset(4.0);
        make.bottom.equalTo(self.contentView).with.offset(-4.0);
    }];

    // **** This block results in respecting tableview margins, but height constraints of background are not respected.  Comment it out to create image "B".
    [self.contentView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.leading.equalTo(self.mas_leadingMargin);
        make.trailing.equalTo(self.mas_trailingMargin);
        make.top.equalTo(self.mas_top).with.priorityHigh();
        make.bottom.equalTo(self.mas_bottom).with.priorityHigh();
    }];
    // **** End problematic block

// Subclass
    [self.courseImageView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.leading.equalTo(self.contentView).with.offset(8.0);
        make.height.and.width.equalTo(self.contentView.mas_width).multipliedBy(.20).with.priorityHigh();
        make.centerY.equalTo(contentView);
    }];
    [self.background mas_makeConstraints:^(MASConstraintMaker *make) {
        make.leading.equalTo(self.courseImageView.mas_trailing).with.offset(8.0);
        make.height.greaterThanOrEqualTo(self.courseImageView).with.priorityMedium();
        make.height.equalTo(self.courseImageView).with.priorityLow();
    }];

A.) 在这里,内容框的高度是正确的,但不考虑边距

B.)在这里,边距得到尊重,但 background 已扩大到荒谬的数量。此外,当它像这样重新加载时,表格视图会向上滚动。

【问题讨论】:

    标签: ios uitableview autolayout masonry


    【解决方案1】:

    您需要检查 Masonry 默认应用的优先级。他们的文件没有明确说明这一点。

    Masonry - Learn to Priortize

    步骤 #1

    尝试在有问题的块内为leading / trailing 设置高优先级-

    // **** This block results in respecting tableview margins, but height constraints of background are not respected.  Comment it out to create image "B".
        [self.contentView mas_makeConstraints:^(MASConstraintMaker *make) {
            make.leading.equalTo(self.mas_leadingMargin).with.priorityHigh();
            make.trailing.equalTo(self.mas_trailingMargin).with.priorityHigh();
            make.top.equalTo(self.mas_top).with.priorityHigh();
            make.bottom.equalTo(self.mas_bottom).with.priorityHigh();
        }];
        // **** End problematic block
    

    步骤 #2

    尝试将backgroundColor 设置在cell.contentView 上,看看它在您的案例A 和B 中延伸多远。这会给您一个更好的主意。

    第 3 步(不推荐的方法,最坏的情况)

    什么都解决不了。

    • 将表的leading/trailing 部分layoutMargins 重置为0
    • 在您的子类的cell.contentView 内添加一个新的wrapperView,并将其leading/trailing 设置为预期值。
    • 如果您不想添加wrapperView,请将预期的leading/trailing 值用作leading/trailing 的直接值,用于cell.contentView 中的所有组件。

    最终,如果这没有像预期的那样工作,你想追多远最终取决于你的选择。有时我不得不安顿在#3。希望对您有所帮助。

    【讨论】:

    • 塔伦,感谢您的回答。我最终并没有直接使用您的任何建议,但只是想想如果我更改 contentView 背景颜色会发生什么会发生,这让我意识到我忽略了高度代码中的布局边距。所以我接受了我自己的答案,但赏金是你让我朝着正确的方向开始。
    【解决方案2】:

    最后,代码当然完全按照我说的去做了。上面的代码设置高度(大于或)等于表格视图单元格宽度的 20%。然而,这是在设置高度时忽略了布局边距,导致了奇怪的行为。

    除此之外,我不认为在父类中对 contentView 添加约束是正确/必要的。只需添加 availableWidth 视图即可解决我在 iPad 上的问题,但在 iPhone 上布局再次中断。为了让两个平台都能正确布局,我必须更改我的基类约束,如下所示。

    这是我更新的代码:

    // Base Class
        [self.background mas_makeConstraints:^(MASConstraintMaker *make) {
            make.leading.equalTo(self.contentView.mas_leadingMargin).with.priorityMedium();
            make.trailing.equalTo(self.contentView.mas_trailingMargin).with.priorityMedium();
            make.top.equalTo(self.contentView.mas_top).with.offset(4.0);
            make.bottom.equalTo(self.contentView.mas_bottom).with.offset(-4.0);
        }];
    // *** Constraints on self.contentView are not necessary to respect the default margins! ***
    
    // Subclass
        ...
        UIView *availableWidth = [UIView new];
        availableWidth.hidden = YES;
        [self.contentView addSubview:availableWidth];
    
        [self.courseImageView mas_makeConstraints:^(MASConstraintMaker *make) {
            make.leading.equalTo(self.contentView.mas_leadingMargin);
            make.height.and.width.equalTo(availableWidth.mas_width).multipliedBy(.20);
            make.centerY.equalTo(contentView);
        }];
        [self.background mas_makeConstraints:^(MASConstraintMaker *make) {
            make.leading.equalTo(self.courseImageView.mas_trailing).with.offset(8.0);
            make.height.greaterThanOrEqualTo(availableWidth.mas_width).multipliedBy(.20).with.priorityHigh();
        }];
        [availableWidth mas_makeConstraints:^(MASConstraintMaker *make) {
            make.leading.equalTo(self.contentView.mas_leadingMargin);
            make.trailing.equalTo(self.contentView.mas_trailingMargin);
            make.height.equalTo(@0);
            make.top.equalTo(self.contentView);
        }];
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-03
      • 1970-01-01
      • 2020-09-07
      • 2015-06-20
      相关资源
      最近更新 更多