如何在 Swift 中设置自定义视图的固有内容大小?
How to set a custom view's intrinsic content size in Swift?
背景
我正在制作一个垂直标签以使用传统的蒙古文字。在我只是旋转 UILabel
之前,但存在一些性能问题和其他并发症。现在我正在努力从头开始制作标签。但是,我需要垂直标签在高度调整时告诉自动布局(基于字符串长度)。
我读了什么
我阅读了 Intrinsic Content Size and Views with Intrinsic Content Size 文档。不过,这些更多是关于如何使用它,而不是如何在自定义视图中定义它。
搜索 "ios intrinsic content size for a custom view" 只给我
- Proper usage of intrinsicContentSize and sizeThatFits: on UIView Subclass with autolayout
在堆栈溢出中。这个特定问题甚至不需要固有内容大小,因为他们的视图只是标准视图的集合。
我正在尝试什么
我正在尝试的是下面的答案。我添加了这个问答对,这样其他人就不会像我使用搜索关键字那样花很长时间找到答案。
设置自定义视图的固有内容大小可以让自动布局知道该视图需要多大。为了设置它,您需要覆盖 intrinsicContentSize
.
override var intrinsicContentSize: CGSize {
return CGSize(width: x, height: y)
}
然后调用
invalidateIntrinsicContentSize()
每当您的自定义视图的固有内容大小发生变化并且应更新框架时。
备注
- Swift 3 更新: Easier Auto Layout: Coding Constraints in iOS 9
- 仅仅因为您在自定义视图中设置了固有内容大小并不意味着它会按您预期的那样工作。阅读 the documentation for how to use it, paying special attention to Content-Hugging and Compression-Resistance.
- 也感谢这个问答让我走上正轨:How can I add padding to the intrinsic content size of UILabel?
- 也感谢 this article and the documentation 在
invalidateIntrinsicContentSize()
方面的帮助。
“具有固有高度的视图”示例 ...
@IBDesignable class HView: UIView {
@IBInspectable var height: CGFloat = 100.0
override var intrinsicContentSize: CGSize {
return CGSize(width: 99, height: height)
// if using in, say, a vertical stack view, the width is ignored
}
override func prepareForInterfaceBuilder() {
invalidateIntrinsicContentSize()
}
}
您可以将其设置为可检查项
因为它有一个固有的高度,它可以(例如)立即插入代码中的堆栈视图中:
stack?.insertArrangedSubview(HView(), at: 3)
相反,如果它是没有固有高度的普通视图,则必须添加高度锚点,否则它会崩溃:
let v:UIView = HView()
v.heightAnchor.constraint(equalToConstant: 100).isActive = true
stack?.insertArrangedSubview(v, at: 3)
注意在...
堆栈视图的重要特例:
- 您只设置了 ONE 锚点(对于垂直堆栈视图,高度;对于水平宽度)
因此,设置固有高度非常有效,因为:
- 固有高度确实意味着高度锚点将在需要时自动设置。
请记住,在子视图的所有正常情况下,还需要许多其他锚点。
背景
我正在制作一个垂直标签以使用传统的蒙古文字。在我只是旋转 UILabel
之前,但存在一些性能问题和其他并发症。现在我正在努力从头开始制作标签。但是,我需要垂直标签在高度调整时告诉自动布局(基于字符串长度)。
我读了什么
我阅读了 Intrinsic Content Size and Views with Intrinsic Content Size 文档。不过,这些更多是关于如何使用它,而不是如何在自定义视图中定义它。
搜索 "ios intrinsic content size for a custom view" 只给我
- Proper usage of intrinsicContentSize and sizeThatFits: on UIView Subclass with autolayout
在堆栈溢出中。这个特定问题甚至不需要固有内容大小,因为他们的视图只是标准视图的集合。
我正在尝试什么
我正在尝试的是下面的答案。我添加了这个问答对,这样其他人就不会像我使用搜索关键字那样花很长时间找到答案。
设置自定义视图的固有内容大小可以让自动布局知道该视图需要多大。为了设置它,您需要覆盖 intrinsicContentSize
.
override var intrinsicContentSize: CGSize {
return CGSize(width: x, height: y)
}
然后调用
invalidateIntrinsicContentSize()
每当您的自定义视图的固有内容大小发生变化并且应更新框架时。
备注
- Swift 3 更新: Easier Auto Layout: Coding Constraints in iOS 9
- 仅仅因为您在自定义视图中设置了固有内容大小并不意味着它会按您预期的那样工作。阅读 the documentation for how to use it, paying special attention to Content-Hugging and Compression-Resistance.
- 也感谢这个问答让我走上正轨:How can I add padding to the intrinsic content size of UILabel?
- 也感谢 this article and the documentation 在
invalidateIntrinsicContentSize()
方面的帮助。
“具有固有高度的视图”示例 ...
@IBDesignable class HView: UIView {
@IBInspectable var height: CGFloat = 100.0
override var intrinsicContentSize: CGSize {
return CGSize(width: 99, height: height)
// if using in, say, a vertical stack view, the width is ignored
}
override func prepareForInterfaceBuilder() {
invalidateIntrinsicContentSize()
}
}
您可以将其设置为可检查项
因为它有一个固有的高度,它可以(例如)立即插入代码中的堆栈视图中:
stack?.insertArrangedSubview(HView(), at: 3)
相反,如果它是没有固有高度的普通视图,则必须添加高度锚点,否则它会崩溃:
let v:UIView = HView()
v.heightAnchor.constraint(equalToConstant: 100).isActive = true
stack?.insertArrangedSubview(v, at: 3)
注意在...
堆栈视图的重要特例:
- 您只设置了 ONE 锚点(对于垂直堆栈视图,高度;对于水平宽度)
因此,设置固有高度非常有效,因为:
- 固有高度确实意味着高度锚点将在需要时自动设置。
请记住,在子视图的所有正常情况下,还需要许多其他锚点。