我有一个自定义视图,其中包含标签(假设标签固定在视图的所有边缘)。自定义视图的宽度取决于text属性(自然,文本越长,视图将越长)。
但是,出现了问题。当我实例化let customView = CustomView()
并向标签customView.textLabel.text "New text"
分配新文本时,自定义视图的框架仍为零。我认为这是因为我一开始没有设置框架。
如果我决定在初始化时间(let customView = CustomView(CGFrame(...))
)设置初始帧,然后更新标签内容,则该帧不会更改其width
。为什么?我如何有一个动态视图来使其框架适应其内容?在标签或视图上调用sizeToFit
不会更改框架。
答案 0 :(得分:2)
我如何拥有一个可以根据其内容调整其框架的动态视图?
通常的做法是使用自动布局放置视图并覆盖intrinsicContentSize
以根据内容视图(例如标签)提供宽度和高度。自动布局引擎将自动遵守intrinsicContentSize
。
请注意,内在内容大小并不神奇地知道其自身的依赖性。每次更改依赖项(例如标签的文本)时,由您决定调用invalidateIntrinsicContentSize
,以便再次调用intrinsicContentSize
以重新计算高度和宽度。
在此示例中,CustomView是红色视图,其内部带有白色背景的标签是其textLabel
。请注意,随着标签文本的更改,红色视图如何与标签的自动扩展和收缩同步地自动扩展和收缩。
这是一个非常简单的示例,出于说明目的,因此我对CustomView的实现非常简单:
class CustomView : UIView {
@IBOutlet var textLabel : UILabel!
override var intrinsicContentSize: CGSize {
let w = self.textLabel.intrinsicContentSize.width + 40
let h = self.textLabel.intrinsicContentSize.height + 40
return CGSize(width: w, height: h)
}
}
现在这些按钮就说明了这种事情:
self.customView.textLabel.text = // whatever
self.customView.invalidateIntrinsicContentSize()
答案 1 :(得分:0)
您可以尝试
let customView = CustomView(frame:CGRect.zero)
customView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(customView)
NSLayoutConstraint.activate([
customView.topAnchor.constraint(equalTo: self.view.topAnchor,constant: 50),
customView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor,constant: 20)
])
customView.lbl.text = "fjdfjdfkjkdfjkdfjjfkdjfkdjkdfjkdfjkdfjfkdjdfkjdfkjkffkj"
class CustomView: UIView {
var lbl:UILabel!
override init(frame: CGRect) {
super.init(frame: frame)
createSubviews()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
createSubviews()
}
func createSubviews() {
// craete the label and pin it to all anchors with .lines = 0
lbl = UILabel()
lbl.translatesAutoresizingMaskIntoConstraints = false
lbl.lines = 0
self.addSubview(lbl)
NSLayoutConstraint.activate([
lbl.topAnchor.constraint(equalTo: self.topAnchor),
lbl.leadingAnchor.constraint(equalTo: self.leadingAnchor),
lbl.trailingAnchor.constraint(equalTo: self.trailingAnchor),
lbl.bottomAnchor.constraint(equalTo: self.bottomAnchor)
])
}
}
注意:要包装的标签/它的父标签必须有宽度
答案 2 :(得分:0)
首先,我们需要查看您的自定义类的代码 但据我所记得,您需要设置约束来确定视图的大小。最简单的方法是使用xcode创建一个皮肤视图。 tutorial here 但我认为您已经对此熟了。因此,有时您需要告诉Swift uikit重新生成/刷新约束。