我尝试将UIStackView子类化并添加一些我想要的控件。我添加一个UIView作为容器,所有其他视图,如UILabel,UIButton,UIImageView等,将作为子视图添加到容器中。
class UIButtonHeaderView: UIStackView {
// MARK: - Properties
var container: UIView!
var titleLabel: UILabel!
// MARK: - Initialization
private func setUp() {
// Set container.
container = UIView()
container.backgroundColor = .blue
addArrangedSubview(container)
// Set label.
titleLabel = UILabel()
container.addSubview(titleLabel)
titleLabel.translatesAutoresizingMaskIntoConstraints = false
titleLabel.leadingAnchor.constraint(equalTo: container.leadingAnchor).isActive = true
titleLabel.bottomAnchor.constraint(equalTo: container.bottomAnchor).isActive = true
titleLabel.trailingAnchor.constraint(lessThanOrEqualTo: container.trailingAnchor).isActive = true
titleLabel.widthAnchor.constraint(greaterThanOrEqualToConstant: 0).isActive = true
titleLabel.heightAnchor.constraint(greaterThanOrEqualToConstant: 0).isActive = true
titleLabel.text = "This is just a simple test!!"
titleLabel.backgroundColor = .green
titleLabel.textColor = .red
titleLabel.sizeToFit()
}
override init(frame: CGRect) {
super.init(frame: frame)
setUp()
}
required init(coder: NSCoder) {
super.init(coder: coder)
setUp()
}
}
代码工作正常,但是当我替换
时我遇到了麻烦var container: UIView!
var titleLabel: UILabel!
与
weak var container: UIView!
weak var titleLabel: UILabel!
我认为类UIButtonHeaderView的实例及其属性(container和titleLabel)可能有引用循环问题,所以我尝试在var前面添加弱,这会导致我的App崩溃。
Xcode告诉我这行
container.backgroundColor = .blue
错误消息错误
Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value
似乎就行了
container = UIView()
无法创建类UIView的实例,因此容器为nil,导致App崩溃,但我不知道原因。
答案 0 :(得分:2)
你必须制作选项,因为当我们拥有一个包含对象弱引用的属性时,它的类型应该是可选的,因为它有能力在运行时变为nil。
weak var container: UIView?
weak var titleLabel: UILabel?
答案 1 :(得分:1)
要扩展Rob的答案,如果你的属性弱可选,你仍然会遇到问题。
当你这样说时:
container = UIView()
对新创建的视图没有强烈的引用,因此在您有机会将其添加到堆栈视图之前,它将立即发布并且container
将变为nil
。
要解决此问题,您需要使用局部变量来保存UIView
引用,直到将其添加为子视图;此时,堆栈视图将包含一个强引用,您可以将引用分配给weak
属性,并让局部变量超出范围而不释放视图。
let newContainer = UIView()
newContainer.backgroundColor = .blue
addArrangedSubview(newContainer)
container = newContainer
我同意Rob的评论; subclassinf UIStackView
可能不是正确的方法。
答案 2 :(得分:0)
要扩展Khushbu的答案,请:
weak var container: UIView!
weak var titleLabel: UILabel!
表示(通过weak
),如果对象被释放,您希望此值变为nil
,并且(通过!
)您保证,如果它,您将永远不会访问它是nil
。这些是相互矛盾的。