UITableViewCell:无法同时满足约束

时间:2015-07-02 18:05:22

标签: ios objective-c uitableview autolayout

我已经创建了UITableViewCell我正在使用自动布局,其中约束完全由代码构建。

虽然应用程序中的实际输出很好(即,它看起来就像我设计的那样),但我得到了着名的"无法同时满足约束"错误/警告信息。

以下是错误消息打印的约束列表:

"<NSLayoutConstraint:0x7fb2f280e5e0 V:|-(0)-[UIScrollView:0x7fb2f0435730]   (Names: '|':UITableViewCellContentView:0x7fb2f04345c0 )>",
"<NSLayoutConstraint:0x7fb2f280e880 V:[UIScrollView:0x7fb2f0435730(280)]>",
"<NSLayoutConstraint:0x7fb2f280e630 V:[UIScrollView:0x7fb2f0435730]-(16)-[UIScrollView:0x7fb2f04360d0]>",
"<NSLayoutConstraint:0x7fb2f280e920 V:[UIScrollView:0x7fb2f04360d0(140)]>",
"<NSLayoutConstraint:0x7fb2f280e970 V:[UIScrollView:0x7fb2f04360d0]-(16)-[SummaryView:0x7fb2f0436c20]>",
"<NSLayoutConstraint:0x7fb2f280e9f0 V:[SummaryView:0x7fb2f0436c20(140)]>",
"<NSLayoutConstraint:0x7fb2f280e8d0 V:[SummaryView:0x7fb2f0436c20]-(0)-|   (Names: '|':UITableViewCellContentView:0x7fb2f04345c0 )>",
"<NSLayoutConstraint:0x7fb2f0439e30 'UIView-Encapsulated-Layout-Height' V:[UITableViewCellContentView:0x7fb2f04345c0(44)]>"

它们中的每一个都是完全正确的,正是我想要的,除了最后一个。系统生成的很明显。 44分是(我相信)系统标准的单元格高度。对我来说好奇的是我明确说明了正确的细胞高度(在这种情况下,592个点)。这是我在UITableViewController子类中所做的:

- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath {
    return [TableViewCell heightNeededForCell];
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    return [TableViewCell heightNeededForCell];
}

我认为发生这种情况的原因是因为我的手机init功能:

#pragma mark - Table View Cell Lifecycle
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self != nil) {
        [self setupUserInterface];
    }
    return self;
}

#pragma mark - UI Setup
- (void)setupUserInterface {
    [self createControls];
    [self createConstants];
    [self setupControls];
    [self layoutControls];
    [self.contentView layoutIfNeeded]; <-- Here's where the warning occurs
    // The UIScrollViews (which contain UIImageViews) were not
    // adjusting their contentSize properly, so I do it manually here
    self.scrollView1.contentSize = self.heartImageView1.bounds.size;
    self.scrollView2.contentSize = self.heartImageView2.bounds.size;
    }
}

从我的结果来看,似乎我可以放心地忽略这个错误,但我有点挑剔而且不喜欢我收到警告的事实,即使我可以解释它并且它似乎没有造成任何麻烦。如何成功更改系统提供的约束?

1 个答案:

答案 0 :(得分:3)

你是对的,意外的约束来自UITableView机器本身。

我认为当你在初始化程序中调用layoutIfNeeded时,你会混淆UITableView机器,它需要负责整个单元格的布局,并确保单元格包装它正确拥有contentView。所以你已经告诉contentView布局,但是细胞本身并没有被告知在正确的时间串联布局。什么是合适的时间?只有UITableView知道自己的秘密......

解决这个问题可能不止一种方法,但我建议切换到使用自行调整大小的单元格。通过这种方式,您将对UITableView期望您处理的内容负责,从而减少出现意外的空间。由于您已经使用自动布局定义了单元格的布局,因此几乎已经存在。

以下是如何操作:

  1. 只需向内容视图添加另一个布局约束,将其约束到所需的592点高度。

  2. 然后完全删除tableView:estimatedHeightForRowAtIndexPathtableView:heightForRowAtIndexPath的委托方法。

  3. 然后在tableView.estimatedRowHeight = 600中设置viewDidLoad(或实际上的任何值)。

  4. 现在tableView会将单元格设置为高度592,这是单元格通过自己的自动布局约束声明自己喜欢的高度。

    这里有很多方法可以做到这一点:https://github.com/algal/TableViewSpike

    注意:自行调整大小的单元需要iOS 8.0或更高版本的部署目标。