在iOS 11上,由于标签显然误报了它们的internalContentSize,我们的许多布局都被破坏了。
当将UILabel包装在另一个试图实现intrinsicContentSize
自身的视图中时,该错误似乎最严重。像这样(简化和人为的示例):
class LabelView: UIView {
let label = UILabel()
override init(frame: CGRect) {
super.init(frame: frame)
self.setup()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private func setup() {
self.label.textColor = .black
self.label.backgroundColor = .green
self.backgroundColor = .red
self.label.numberOfLines = 0
self.addSubview(self.label)
self.label.translatesAutoresizingMaskIntoConstraints = false
self.label.leadingAnchor.constraint(equalTo: self.leadingAnchor).isActive = true
self.label.trailingAnchor.constraint(lessThanOrEqualTo: self.trailingAnchor).isActive = true
self.label.topAnchor.constraint(equalTo: self.topAnchor).isActive = true
self.label.bottomAnchor.constraint(equalTo: self.bottomAnchor).isActive = true
}
override var intrinsicContentSize: CGSize {
let size = self.label.intrinsicContentSize
print(size)
return size
}
}
在intrinsicContentSize
该的UILabel的是非常独特的,看起来是这样的:(width: 1073741824.0, height: 20.5)
。这将导致布局周期为视图的包装器提供太多空间。
仅当从XCode 9为iOS 11编译时会发生这种情况。在由iOS 10 SDK(在XCode 8上)编译的iOS 11上运行时。
在XCode 8(iOS 10)上,视图可以正确呈现,如下所示:
在XCode 9(iOS 11)上,视图呈现如下:
满操场代码演示此问题的一个要点是这里。
我已经为此提交了雷达,并且至少有一个解决该问题的方法(请参阅下面的答案)。我想知道是否有人遇到了这个问题或您是否可以尝试其他方法。
因此,通过在操场上进行实验,我能够提出一种解决方案,其中涉及对非常大的固有内容大小进行测试。
我注意到,所有行为不当的UILabel都有numberOfLines==0
和preferredMaxLayoutWidth=0
。在随后的布局传递中,UIKit会将preferredMaxLayoutWidth设置为非零值,大概是迭代到标签的正确高度。因此,第一个解决方法是尝试临时设置numberOfLines
when (self.label.numberOfLines == 0 && self.label.preferredMaxLayoutWidth == 0)
。
我还注意到,将这两个属性都设置为0的所有UILabel不一定行为不当。(即反事实并非如此)。因此,此修复程序有效,但有时会不必要地修改标签。它还有一个小错误,当标签的文本包含\n
换行符时,应将行数设置为字符串中的行数,而不是1。
我来到的最后一个解决方案有点棘手,但专门查找UILabel行为异常,然后才解决问题...
override var intrinsicContentSize: CGSize {
guard super.intrinsicContentSize.width > 1000000000.0 else {
return super.intrinsicContentSize
}
var count = 0
if let text = self.text {
text.enumerateLines {(_, _) in
count += 1
}
} else {
count = 1
}
let oldNumberOfLines = self.numberOfLines
self.numberOfLines = count
let size = super.intrinsicContentSize
self.numberOfLines = oldNumberOfLines
return size
}
您可以在此处找到要点。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句