美文网首页程序员
UITableViewCell自动计算高度时的约束警告

UITableViewCell自动计算高度时的约束警告

作者: LittleYuz | 来源:发表于2018-10-21 17:19 被阅读24次

    具体业务

    UITableViewCell 中嵌套一个 UICollectionView,Cell 的高度需要根据 CollectionView items 个数动态变化

    image

    遇到的问题

    最后实现的效果是没有问题的,但会出现这样的约束警告

    [LayoutConstraints] Unable to simultaneously satisfy constraints.
        Probably at least one of the constraints in the following list is one you don't want. 
        Try this: 
            (1) look at each constraint and try to figure out which you don't expect; 
            (2) find the code that added the unwanted constraint or constraints and fix it. 
    [
        <MASLayoutConstraint:0x600002c6e6a0 UILabel:0x7ffc5fcf4bc0.top == XBHDemandRegionHotCitiesCell:0x7ffc611b3a00.top + 15>,
        <MASLayoutConstraint:0x600002c6ed60 UICollectionView:0x7ffc60a93c00.top == UILabel:0x7ffc5fcf4bc0.bottom + 5>,
        <MASLayoutConstraint:0x600002c6edc0 UICollectionView:0x7ffc60a93c00.bottom == XBHDemandRegionHotCitiesCell:0x7ffc611b3a00.bottom - 10>,
        <MASLayoutConstraint:0x600002c6efa0 UICollectionView:0x7ffc60a93c00.height == 70>,
        <NSLayoutConstraint:0x600002b52c60 DemandRegionHotCitiesCell:0x7ffc611b3a00.height == 44.3333>
    ]
    
    Will attempt to recover by breaking constraint 
    <MASLayoutConstraint:0x600002c6efa0 UICollectionView:0x7ffc60a93c00.height == 70>
    
    Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
    The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKitCore/UIView.h> may also be helpful.
    

    强迫症表示真的不能忍!!!

    分析问题的根源

    从警告中可以看到,Cell 有一个高度为 44.3333 的高度约束, 与 CollectionView 的高度为70约束产生了冲突,那么Cell的高度为44.3333的高度约束是从何而来的呢?

    - (void)setCities:(NSArray<XBHRegion *> *)cities {
        _cities = [cities copy];
        [self.collectionView reloadData];
        NSInteger rowCount = ceil(_cities.count / ColumnCount);
        NSInteger spcingCount = MAX(rowCount - 1, 0);
        CGFloat collectionViewHeight = self.flowLayout.minimumLineSpacing * spcingCount + self.flowLayout.itemSize.height * rowCount;
        [self.collectionView mas_updateConstraints:^(MASConstraintMaker *make) {
            make.height.mas_equalTo(collectionViewHeight);
        }];
    }
    

    更新 CollectionView 的高度是在上述代码中实现的,那么初次赋值时,cities的个数为0,导致 Cell 高度为 44.3333
    所以猜想在cities有值时,系统在重新 layout 时,并没有把原先 高度为 44.3333 的约束移除,产生了约束冲突警告。

    解决思路

    Q:如果把这个 UICollectionView 的换成一个 UILabel 会不会产生警告呢?
    A:答案当然是不会的,这种业务以前已经做过多次。
    Q:那么为什么换成 UILabel 就不会呢?
    A:是不是要反过来想,UILabel 是没有设置高度约束的,他是如何确定高度来“撑大” Cell的?

    到这里,想必大家已经知道答案了。UILabel 是根据其内容来自动计算大小的,也就是intrinsicContentSize,转换为约束的优先级是 ContentHuggingPriority 默认是 750,而我们给 UICollectionView 添加的高度约束默认是 1000 的, 那么改一下不就ok了!

     make.height.mas_equalTo(collectionViewHeight).priorityMedium()
    

    大功告成!!!

    相关文章

      网友评论

        本文标题:UITableViewCell自动计算高度时的约束警告

        本文链接:https://www.haomeiwen.com/subject/nkgbzftx.html