(我将这个问题发布为 S.O.(“回答你自己的问题”)格式,以使这个食谱易于找到,并获得任何其他有用的观点)。
问题:设置特定内容大小的 UIViews 有什么方便的方法?
驱动问题的用例:
我正在使用一个包含许多
UIStackView
实例的应用程序,这些实例彼此相邻显示自定义图标。
堆栈视图项通常是
UILabel
其他时候,只是 UIView
.
Apple Docs 说
UILabel
是一种设置自己的内在内容大小的类型。在许多情况下,效果还不错。但是,对于某些 UILabel
实例,内在内容大小并未设置为最佳,这对于让 UIStackView
精确布局可能具有挑战性。
在其他情况下,我创建了一个
UIView
,其中对我创建的每个 UIView
进行子类化并不是最佳选择,而是在创建视图后将 CALayer
渲染到视图中。因此 UIView
无法正确设置其固有大小。因此,当我将它用作 UIStackView
中的项目时,无论帧设置如何,它都会将内容 CGSize 视为 (0, 0),因此即使使用间距和自定义间距选项,UIStackView
也无法正确处理它。
因为我预先知道我正在渲染的图层的大小,所以能够以预定大小构造
UIView
会很有帮助,类似于人们通常构造UIView(frame: CGRectMake(x, y, w, h)
的方式,但是在UIStackView
识别方式(例如内在内容大小)。
这里有一个类允许创建具有特定早期已知内在内容大小的视图(类似于默认的
frame:
构造函数),但大小为UIStackView
荣誉,例如,CALayer
对象可以在之后呈现视图的创建:
class AdjIntrinsicSizeView : UIView {
var size : CGSize = CGSize.zero
required init?(coder: NSCoder) {
fatalError("init?(coder: NSCoder) unimplemented")
}
override init(frame: CGRect) {
super.init(frame: frame)
}
convenience init(size: CGSize = CGSize.zero, frame: CGRect = CGRect.zero) {
self.init(frame: frame);
self.size = size
}
override var intrinsicContentSize: CGSize { size }
}
用法示例:
let iconView = AdjIntrinsicSizeView(size: CGSizeMake(15, 15))
renderDrawing(into: iconView)
let stackView = UIStackView(arrangedItems: [iconView, ...])