我知道添加约束的最佳位置是viewDidLoad,但对于自定义视图,特别是对于自定义单元格,我希望将所有这些布局细节隐藏到自身,而不暴露给它的控制器。而且我不希望VC向其视图发送消息,因为它对耦合贡献了一点,我最讨厌。所以我应该在init方法或layoutSubview中添加约束,还是其他什么?
答案 0 :(得分:0)
如果不使用故事板,我会说添加约束的最佳位置是UITableViewCell
的init方法:
class CustomTableViewCell : UITableViewCell {
lazy var subview: UIView = {
let view = UIView()
view.backgroundColor = .orange
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
contentView.addSubview(subview)
NSLayoutConstraint.activate([
subview.leadingAnchor.constraint(equalTo: contentView.leadingAnchor),
subview.trailingAnchor.constraint(equalTo: contentView.trailingAnchor),
subview.topAnchor.constraint(equalTo: contentView.topAnchor),
subview.bottomAnchor.constraint(equalTo: contentView.bottomAnchor),
subview.heightAnchor.constraint(equalToConstant: 230.0)
])
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
答案 1 :(得分:0)
对于UITableViewCell
子类,通常会在将子视图添加到视图层次结构的任何位置添加约束。
对于NIB中的控件,我在Interface Builder中添加了约束,无需以编程方式执行任何操作。
如果您正在使用NIB,但由于某种原因选择不将约束放在XIB中,您可以在awakeFromNib
中以编程方式创建约束。您不会尝试在init(coder:)
中添加这些约束,因为这些出口尚未连接。您希望在awakeFromNib
中执行此操作,此时它们会被连接起来。
如果您正在使用NIB,但是再次以编程方式添加一些其他子视图,则可以在awakeFromNib
中添加这些子视图及其相关约束。如果这些新的子视图不需要任何@IBOutlet
引用,理论上您也可以在init(coder:)
中执行此操作。
如果您没有使用NIB,而是完全以编程方式创建单元格的子视图,那么您通常会在init(coder:)
或init(style:reuseIdentifier:)
中执行此操作,具体取决于方式cellForRowAt
实例化了单元格。
如今,您通常会为表格视图的重复使用标识符注册一个类,然后cellForRowAt
只会注册dequeueReusableCell(withIdentifier:for:)
,在这种情况下,您可以使用init(coder:)
在dequeueReusableCell(withIdentifier:for:) method
。
在iOS有这个IndexPath
例程之前回来(即我们只有dequeueReusableCell(withIdentifier:)
参数的再现),我们调用nil
,如果它返回init(style:reuseIdentifier:)
,我们使用cellForRowAt
手动实例化单元格。但是这种技术已经不再使用了。
从历史角度来看,值得注意的是,您仍然可能会遇到在UITableViewCell
中添加单元格子视图的旧代码。但我们通常更喜欢将此单元格自定义代码移动到function myFunction(x) {
x.classList.toggle("fa-check");
}
子类中,以帮助最小化视图控制器膨胀。
底线,您可以在将视图层次结构添加到视图层次结构的任何位置添加约束,以及将其放入哪种方法取决于您实例化单元格的方式。