ios - Swift iOS - setContentHuggingPriority 优先考虑错误的标签
问题描述
我有一个带有 4 个标签的单元格:
2 个独立的静态标签和 2 个独立的动态标签。2 个静态标签中的文本始终显示Receipt #,另一个显示Receipt Date。
我设置它的方式是静态标签都具有固定到单元格的 contentView 的leadingAnchor 的前导锚。他们都setContentHuggingPriority
设置为High
并setContentCompressionResistancePriority
设置为Low
。他们的 bottomAnchors 附加到每个匹配的动态标签上lastBaseLineAnchor
动态标签都将其尾随锚钉固定到 contentView 的 trailingAnchor。
收据NumberLabel 的leadingAnchor 被固定到receiptDateLabel 的leadingAnchor。
receiveDateLabel 的leadingAnchor 被固定在距离staticReceiptDateLabel 10 点的位置。这个标签应该是灵活的,但它不是。由于receiptNumberLabels 的leadingAnchor 跟随它,它也没有对齐。
如您所见,staticReceiptDateLabel 较长,但应该更短,receiptDateLabel 应该更长。我已经尝试了不同的值组合,setContentHuggingPriority
但setContentCompressionResistancePriority
无论我不断得到这些结果,我该如何解决这个问题?
contentView.addSubview(receiptNumberLabel) // dynamic
contentView.addSubview(staticReceiptNumberLabel)
contentView.addSubview(receiptDateLabel) // dynamic
contentView.addSubview(staticReceiptDateLabel)
receiptNumberLabel.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 10).isActive = true
receiptNumberLabel.leadingAnchor.constraint(equalTo: receiptDateLabel.leadingAnchor, constant: 0).isActive = true
receiptNumberLabel.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -10).isActive = true
receiptNumberLabel.setContentHuggingPriority(.defaultLow, for: .horizontal)
receiptNumberLabel.setContentCompressionResistancePriority(.defaultHigh, for: .horizontal)
staticReceiptNumberLabel.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 10).isActive = true
staticReceiptNumberLabel.lastBaselineAnchor.constraint(equalTo: receiptNumberLabel.lastBaselineAnchor).isActive = true
staticReceiptNumberLabel.setContentHuggingPriority(.defaultHigh, for: .horizontal)
staticReceiptNumberLabel.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
receiptDateLabel.topAnchor.constraint(equalTo: receiptNumberLabel.bottomAnchor, constant: 10).isActive = true
receiptDateLabel.leadingAnchor.constraint(equalTo: staticReceiptDateLabel.trailingAnchor, constant: 10).isActive = true
receiptDateLabel.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -10).isActive = true
receiptDateLabel.setContentHuggingPriority(UILayoutPriority.defaultLow, for: .horizontal)
receiptDateLabel.setContentCompressionResistancePriority(.defaultHigh, for: .horizontal)
staticReceiptDateLabel.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 10).isActive = true
staticReceiptDateLabel.lastBaselineAnchor.constraint(equalTo: receiptDateLabel.lastBaselineAnchor).isActive = true
staticReceiptDateLabel.setContentHuggingPriority(UILayoutPriority.defaultHigh, for: .horizontal)
staticReceiptDateLabel.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
更新
在评论中@bsod 建议根本不要使用拥抱/压缩。我最初没有使用它们并且发生了同样的问题,我作为最后的手段切换到它们。这是没有拥抱/压缩的代码。
receiptNumberLabel.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 10).isActive = true
receiptNumberLabel.leadingAnchor.constraint(equalTo: receiptDateLabel.leadingAnchor, constant: 0).isActive = true
receiptNumberLabel.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -10).isActive = true
staticReceiptNumberLabel.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 10).isActive = true
staticReceiptNumberLabel.lastBaselineAnchor.constraint(equalTo: receiptNumberLabel.lastBaselineAnchor).isActive = true
receiptDateLabel.topAnchor.constraint(equalTo: receiptNumberLabel.bottomAnchor, constant: 10).isActive = true
receiptDateLabel.leadingAnchor.constraint(equalTo: staticReceiptDateLabel.trailingAnchor, constant: 10).isActive = true
receiptDateLabel.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -10).isActive = true
staticReceiptDateLabel.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 10).isActive = true
staticReceiptDateLabel.lastBaselineAnchor.constraint(equalTo: receiptDateLabel.lastBaselineAnchor).isActive = true
解决方案
忘记拥抱/压缩 API 并以此为起点。从左上角的标签开始,从左到右,从上到下。请注意,静态日期标签的顶部锚点固定在收据编号值标签的底部,以防它有多行。
staticReceiptNumberLabel.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 10).isActive = true
staticReceiptNumberLabel.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 10).isActive = true
receiptNumberLabel.topAnchor.constraint(equalTo: staticReceiptNumberLabel.topAnchor).isActive = true
receiptNumberLabel.leadingAnchor.constraint(equalTo: staticReceiptNumberLabel.trailing, constant: 10).isActive = true
receiptNumberLabel.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -10).isActive = true
staticReceiptDateLabel.leadingAnchor.constraint(equalTo: staticReceiptNumberLabel.leadingAnchor).isActive = true
staticReceiptDateLabel.topAnchor.constraint(equalTo: receiptNumberLabel.bottomAnchor).isActive = true
receiptDateLabel.topAnchor.constraint(equalTo: staticReceiptDateLabel.topAnchor).isActive = true
receiptDateLabel.leadingAnchor.constraint(equalTo: staticReceiptDateLabel.trailingAnchor, constant: 10).isActive = true
receiptDateLabel.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -10).isActive = true
receiptDateLabel.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -10).isActive = true
您还可能需要将标题标签显式设置numberOfLines
为 1,否则 UIKit 可能会截断值标签,即使它numberOfLines
是 0。
如果出于某种原因,您甚至不希望静态标签的大小扩大,也许是因为您给了它们背景颜色,那么您可以引入拥抱/压缩 API。如果是这样,静态标签将是:
theStaticLabel.setContentCompressionResistancePriority(.defaultHigh, for: .horizontal)
theStaticLabel.setContentHuggingPriority(.defaultHigh, for: .horizontal)
动态标签将是:
theDynamicLabel.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
theDynamicLabel.setContentHuggingPriority(.defaultLow, for: .horizontal)
推荐阅读
- kotlin - 使字符串以 Kotlin 中的指定前缀开头
- python - 获取 AttributeError 解析 JSON 数据
- python - pandas:将字符串列拆分为多列并动态命名列
- sql - SQL Server 和优化公用表表达式
- android - Fultter Video Plugin 无法处理异常“未处理的异常:PlatformException(通道错误,无法在通道上建立连接。”
- java - “make clean all run”有效,但 Eclipse 上的项目无法运行
- python - Python:如何跳过地图函数中的元素
- android - 从 Native C++ 代码调用 ADB 命令并以字符串形式获取结果
- c++ - 不能 QOverload 私有信号,使用 Qt 文档示例
- wpf - 如果我从一个 IsEditable="True" 的 ComboBox 切换到另一个 ComboBox,WPF 中 DataGrid 的 SelectedItem 不会触发