从日志输出中识别和修复自动布局问题
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)
}
我正在准备一个以多设备信息为中心的 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)
}