【问题标题】:iOS - Autolayout Constraint Errors for Dynamic UITableViewCell ClassiOS - 动态 UITableViewCell 类的自动布局约束错误
【发布时间】:2017-02-20 11:47:49
【问题描述】:

我有一个UITableViewController,它将显示各种自定义UITableViewCell 子类。其中一些类具有动态内容,可能会改变单元格的大小。

其中一些动态内容是通过asynchronous operations生成的,例如下载图片、数据等。然后根据结果确定单元格的正确大小。

当单元格更新其布局时,我收到了很多约束警告。它似乎打破了UITableView 的一些限制(即,在数据下载完成之前单元格的高度为 100,然后更新为 250)

我发现修复这些警告的唯一方法是将delegate 方法添加到在UITableViewController 和调用[tableView reloadData] 中触发的单元格的类中;

不过这是有问题的,因为它最终会重新触发单元的一些异步操作等。

我的问题是,如果您有自定义 UITableViewCell 类,该类具有在表格初始加载并显示单元格后更改单元格大小的动态内容,那么最好的方法是什么?

示例单元格布局:

  • UILabel

  • UIImage

  • UICollectionView 只有在为当前用户找到对象时才会显示。它可能会显示 1-3 行对象的数据(从而改变单元格的高度),或者如果没有为用户找到对象,它将被隐藏。

  • UIButton

这是一个示例警告:

[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. 
(
    "<NSLayoutConstraint:0x17469f2c0 V:|-(5)-[UIView:0x109431f90]   (active, names: '|':UITableViewCellContentView:0x10943fcd0 )>",
    "<NSLayoutConstraint:0x17469f590 V:[UIView:0x109431f90]-(5)-|   (active, names: '|':UITableViewCellContentView:0x10943fcd0 )>",
    "<NSLayoutConstraint:0x174699a00 V:|-(0)-[UILabel:0x102d0b8f0'Welcome!']   (active, names: '|':UIView:0x109431f90 )>",
    "<NSLayoutConstraint:0x174699e10 UILabel:0x102d0b8f0'Welcome!'.height == 32   (active)>",
    "<NSLayoutConstraint:0x17469fcc0 V:[UILabel:0x102d0b8f0'Welcome!']-(0)-[UIView:0x102d019c0]   (active)>",
    "<NSLayoutConstraint:0x17469f770 UIView:0x102d019c0.height == 1   (active)>",
    "<NSLayoutConstraint:0x17469f9a0 V:[UIView:0x102d019c0]-(0)-[UIImageView:0x102da1cb0]   (active)>",
    "<NSLayoutConstraint:0x17469fb30 UIImageView:0x102da1cb0.height == 161   (active)>",
    "<NSLayoutConstraint:0x17469f810 V:[UIImageView:0x102da1cb0]-(16)-[UILabel:0x102d14150'Optional Message']   (active)>",
    "<NSLayoutConstraint:0x174690ef0 V:[UILabel:0x102d14150'Message']-(16)-[UICollectionView:0x103a01a00]   (active)>",
    "<NSLayoutConstraint:0x174880230 V:[UICollectionView:0x103a01a00]-(16)-[UIButton:0x102d7e6a0]   (active)>",
    "<NSLayoutConstraint:0x1748801e0 UIButton:0x102d7e6a0.height == 36   (active)>",
    "<NSLayoutConstraint:0x174883890 V:[UIButton:0x102d7e6a0]-(24)-|   (active, names: '|':UIView:0x109431f90 )>",
    "<NSLayoutConstraint:0x174882850 UICollectionView:0x103a01a00.height == 220   (active)>",
    "<NSLayoutConstraint:0x174882e40 'UIView-Encapsulated-Layout-Height' UITableViewCellContentView:0x10943fcd0.height == 329   (active)>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x174882850 UICollectionView:0x103a01a00.height == 220   (active)>

【问题讨论】:

  • 您是否在异步操作的完成块中尝试过[tableView setNeedsLayout][tableView layoutConstraints]
  • 是的,我仍然收到警告。请参阅下面的答案。

标签: ios uitableview autolayout height


【解决方案1】:

事实证明,在 UITableViewCell 中使用 UIButton 时存在某种错误。

在 UIButton 的垂直间距上更改约束的优先级修复了错误:

曾经:

[NSLayoutConstraint activateConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[label(32)]-[imageView(100)]-16-[button(buttonHeight)]-8-|"选项:NSLayoutFormatAlignAllCenterX 指标:指标视图:视图]];

现在:

[NSLayoutConstraint activateConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[label(32)]-[imageView(100)]-16-[button(buttonHeight)]-8@999- |"选项:NSLayoutFormatAlignAllCenterX 指标:指标视图:视图]];

【讨论】:

    【解决方案2】:

    你必须设置

    tableview.estimatedRowHeight = tableview.rowHeight 
    tableview.rowHeight = UITableView.AutomaticDimension()
    

    在那之后,一切都是关于约束的

    【讨论】:

    • .. 例如,如果您有图像,请设置 SizeToFit 和边距约束
    • 对不起,我实际上已经正确设置了tableView rowHeight 和estimatedRowHeight。问题更多是表格加载单元格,单元格以一个高度开始(让我们说 100),然后异步操作完成并将单元格从它自己的类调整为更大的高度(变化),然后 tableView 生成由于约束错误而发出警告。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多