从日志输出中识别和修复自动布局问题

Identifying and fixing auto layout issue from log output

我正在准备一个以多设备信息为中心的 iOS 应用程序,几乎只在界面构建器情节提要中。我正在使用 table 视图控制器将文本或其他内容放入静态 table 视图单元格中。

在特定的单元格中,我想要一个具有相同高度行但不同宽度的文本字段网格 - 取决于文本字段的长度。

我正在使用包含水平堆栈视图的垂直堆栈视图,所有视图都具有对齐:填充和分布:按比例填充。

如果我不减小最小字体大小,网格在某些设备上根本不会出现,但经过大量摆弄后,我可以使网格出现在 class 大小的模拟器上。 ..

但是,日志显示 "Unable to simultaneously satisfy constraints..."

"<NSLayoutConstraint:0x600002bde620 UITextField:0x7f92608dc200.width == 45   (active)>",
"<NSLayoutConstraint:0x600002bfe210 'fittingSizeHTarget' UIStackView:0x7f925f463d70.width == 0   (active)>",
"<NSLayoutConstraint:0x600002bd2cb0 'UISV-canvas-connection' UIStackView:0x7f925f463d70.leading == UITextField:0x7f92608dc200.leading   (active)>",
"<NSLayoutConstraint:0x600002bd2d00 'UISV-canvas-connection' H:[UITextField:0x7f926081b200]-(0)-|   (active, names: '|':UIStackView:0x7f925f463d70 )>",
"<NSLayoutConstraint:0x600002bd4be0 'UISV-spacing' H:[UITextField:0x7f92608dc200]-(0)-[UITextField:0x7f926081b200]   (active)>"

我从 https://www.wtfautolayout.com 理解的意思是:

TextField1 的宽度应等于 45。

StackView 的宽度应等于 0。

StackView 的前缘应等于 TextField1 的前缘。‡

StackView 的后缘应等于 TextField2 的后缘。‡

TextField2 的前缘应等于 TextField1 的后缘。‡

后三个看起来很熟悉,但我没有安装也找不到宽度限制(我猜是基于内容)。

然后日志报告打破上面列表中的第一个约束似乎是解决方案,但另一个非常相似的日志错误紧随其后,但值略有不同 - 可能是网格中的下一行。

我的问题是准确地确定发生这种情况的位置、发生原因以及如何有效地解决它。

您的情节提要中的 UITextField 宽度似乎设置为 45 作为约束。

在 XCode 中为 UIViewAlertForUnsatisfiableConstraints 添加 Symbolic constraint 并尝试调试问题。

根据评论,我尝试使用 UICollectionView 创建一个像 table 这样的网格。下面的代码参考源代码。与安排静态内容和依赖自动布局相比,这是很多工作,但如果自动布局不能提供这种布局,那么我必须接受这个作为答案。

即使使用这种方法,网格中的最后一行也有问题 - 。尽管如此,如果我能让最后一行对齐,并且没有人建议使用约束可以形成网格,那么我将更新并接受这个答案是正确的。

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize
{
    let settings = currentContents[indexPath.item]
    let height = CGFloat(30)

    // 
    var cellWidth = CGFloat()
    let availableWidth = collectionView.bounds.size.width
    print("available width", availableWidth)
    let minimumWidth = floor(availableWidth / collectionContents.cellsPerRow5)
    // let remainder = availableWidth - minimumWidth * CGFloat(cellsPerRow4)
    print("minmum width", minimumWidth)
    cellWidth = minimumWidth * settings.portion - 1
    print("cell width", cellWidth)

    return CGSize(width: cellWidth, height: height)
}