如何创建一个内部带有子视图的自定义 UIView,并以编程方式使用 AutoLayout 设置其 size/position?
How to create a custom UIView with a subview inside, setting its size/position with AutoLayout programmatically?
我想创建一个自定义 UIView
,比如说 TestLabelView
,它包含一个边距为 16px 的标签。
看起来像这样:
以下是我尝试创建此自定义 UIView
并在视图控制器中实例化它的方法:
TestLabelView
class TestLabelView: UIView {
private var label = UILabel()
var text: String = "" { didSet { updateUI() } }
override init(frame: CGRect) {
super.init(frame: frame)
internalInit()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
internalInit()
}
private func internalInit() {
backgroundColor = .red
label.numberOfLines = 0
translatesAutoresizingMaskIntoConstraints = false
addSubview(label)
}
private func updateUI() {
label.text = text
NSLayoutConstraint(item: label,
attribute: .leading,
relatedBy: .equal,
toItem: self,
attribute: .leading,
multiplier: 1,
constant: 24).isActive = true
NSLayoutConstraint(item: self,
attribute: .trailing,
relatedBy: .equal,
toItem: label,
attribute: .trailing,
multiplier: 1,
constant: 24).isActive = true
NSLayoutConstraint(item: label,
attribute: .top,
relatedBy: .equal,
toItem: self,
attribute: .top,
multiplier: 1,
constant: 24).isActive = true
NSLayoutConstraint(item: self,
attribute: .bottom,
relatedBy: .equal,
toItem: label,
attribute: .bottom,
multiplier: 1,
constant: 24).isActive = true
setNeedsUpdateConstraints()
}
}
ViewController
class ViewController: UIViewController {
@IBOutlet weak var testLabelView: TestLabelView?
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
testLabelView?.text = "This is a test view with a test label, contained in multiple lines"
}
}
在情节提要中
我设置了placeholder intrinsic size来去除storyboard错误,bottom margin大于等于24px,所以view height要根据content size设置
但是这样做后,我没有看到标签出现。我做错了什么?
感谢您的帮助
您可以为您的 TestLabelView
视图尝试此代码
class TestLabelView: UIView {
private var label : UILabel = {
let l = UILabel()
l.translatesAutoresizingMaskIntoConstraints = false
l.numberOfLines = 0
return l
}()
var text: String = "" { didSet { self.label.text = self.text } }
override init(frame: CGRect) {
super.init(frame: frame)
internalInit()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
internalInit()
}
private func internalInit() {
backgroundColor = .red
translatesAutoresizingMaskIntoConstraints = false
addSubview(label)
setConstraints()
}
private func setConstraints() {
NSLayoutConstraint.activate([
self.label.topAnchor.constraint(equalTo: self.topAnchor, constant: 16),
self.label.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: 16),
self.label.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: -16),
self.label.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: -16),
])
}
}
我想创建一个自定义 UIView
,比如说 TestLabelView
,它包含一个边距为 16px 的标签。
看起来像这样:
以下是我尝试创建此自定义 UIView
并在视图控制器中实例化它的方法:
TestLabelView
class TestLabelView: UIView {
private var label = UILabel()
var text: String = "" { didSet { updateUI() } }
override init(frame: CGRect) {
super.init(frame: frame)
internalInit()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
internalInit()
}
private func internalInit() {
backgroundColor = .red
label.numberOfLines = 0
translatesAutoresizingMaskIntoConstraints = false
addSubview(label)
}
private func updateUI() {
label.text = text
NSLayoutConstraint(item: label,
attribute: .leading,
relatedBy: .equal,
toItem: self,
attribute: .leading,
multiplier: 1,
constant: 24).isActive = true
NSLayoutConstraint(item: self,
attribute: .trailing,
relatedBy: .equal,
toItem: label,
attribute: .trailing,
multiplier: 1,
constant: 24).isActive = true
NSLayoutConstraint(item: label,
attribute: .top,
relatedBy: .equal,
toItem: self,
attribute: .top,
multiplier: 1,
constant: 24).isActive = true
NSLayoutConstraint(item: self,
attribute: .bottom,
relatedBy: .equal,
toItem: label,
attribute: .bottom,
multiplier: 1,
constant: 24).isActive = true
setNeedsUpdateConstraints()
}
}
ViewController
class ViewController: UIViewController {
@IBOutlet weak var testLabelView: TestLabelView?
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
testLabelView?.text = "This is a test view with a test label, contained in multiple lines"
}
}
在情节提要中
我设置了placeholder intrinsic size来去除storyboard错误,bottom margin大于等于24px,所以view height要根据content size设置
但是这样做后,我没有看到标签出现。我做错了什么?
感谢您的帮助
您可以为您的 TestLabelView
视图尝试此代码
class TestLabelView: UIView {
private var label : UILabel = {
let l = UILabel()
l.translatesAutoresizingMaskIntoConstraints = false
l.numberOfLines = 0
return l
}()
var text: String = "" { didSet { self.label.text = self.text } }
override init(frame: CGRect) {
super.init(frame: frame)
internalInit()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
internalInit()
}
private func internalInit() {
backgroundColor = .red
translatesAutoresizingMaskIntoConstraints = false
addSubview(label)
setConstraints()
}
private func setConstraints() {
NSLayoutConstraint.activate([
self.label.topAnchor.constraint(equalTo: self.topAnchor, constant: 16),
self.label.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: 16),
self.label.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: -16),
self.label.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: -16),
])
}
}