【发布时间】:2016-03-21 14:50:51
【问题描述】:
我经常看到在UIViewController 中添加了自动布局约束,但对我来说,这似乎是布局逻辑的错误位置。
是否可以在自定义UIView 中添加NSLayoutConstraints?
UIView 中的哪个位置适合以编程方式添加它们?
【问题讨论】:
标签: ios swift uiview autolayout uikit
我经常看到在UIViewController 中添加了自动布局约束,但对我来说,这似乎是布局逻辑的错误位置。
是否可以在自定义UIView 中添加NSLayoutConstraints?
UIView 中的哪个位置适合以编程方式添加它们?
【问题讨论】:
标签: ios swift uiview autolayout uikit
是否可以在自定义 UIView 中添加 NSLayoutConstraints?
是的,可以在自定义视图中添加约束,组织在这里非常重要,特别是如果您想为自定义视图的某些部分设置动画。
阅读 Apple 的 UIView Reference document 中的子类化部分
约束:
requiresConstraintBasedLayout - 实现这个类方法,如果你 视图类需要约束才能正常工作。
updateConstraints - 如果您的视图需要创建,请实施此方法 子视图之间的自定义约束。
alignmentRectForFrame:, frameForAlignmentRect: - 实现这些 覆盖视图与其他视图对齐方式的方法。
在 UIView 中的哪个位置以编程方式添加它们是正确的?
这是一个自定义类的框架大纲。关键问题是你集中你的约束,否则你添加的约束越多,类就会变得非常混乱。您还可以在 updateConstraints() 方法中引入其他设置,并通过设置配置值有条件地添加或删除约束,然后调用 setNeedsUpdateConstraints()。
您决定要制作动画的任何约束都应该是实例变量。
希望这会有所帮助:)
class MyCustomView: UIView {
private var didSetupConstraints = false
private let myLabel = UILabel(frame: CGRectZero)
// MARK: Lifecycle
override init(frame: CGRect) {
super.init(frame: CGRectZero)
self.setup()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.setup()
}
// Mark: - Setup
private func setup() {
// 1. Setup the properties of the view it's self
self.translatesAutoresizingMaskIntoConstraints = false
backgroundColor = UIColor.orangeColor()
clipsToBounds = true
// 2. Setup your subviews
setupMyLabel()
// 3. Inform the contraints engine to update the constraints
self.setNeedsUpdateConstraints()
}
private func setupMyLabel() {
myLabel.translatesAutoresizingMaskIntoConstraints = false
}
override func updateConstraints() {
if didSetupConstraints == false {
addConstraintsForMyLabel()
}
super.updateConstraints() //Documentation note: Call [super updateConstraints] as the final step in your implementation.
}
private func addConstraintsForMyLabel() {
// Add your constraints here
}
}
【讨论】:
updateConstraints() 中设置了约束,我相信您忘记将didSetupConstraints 设置为true。
updateConstraints() 中设置了约束,我相信您忘记将didSetupConstraints 设置为true。
self.addSubview(myLabel) ;)
我喜欢在视图中设置我的 AutoLayout 代码更有意义。我还发现在 customView 的 init 中将所有约束设置在一个地方更容易。
import UIKit
class customView:UIView
{
var customLabel:UILabel = UILabel()
override init(frame: CGRect) {
super.init(frame: frame)
self.setupUI()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func setupUI()
{
// Setup UI
self.customLabel.translatesAutoresizingMaskIntoConstraints = false
self.addSubview(customLabel)
// Setup Constraints
self.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-10-[customLabel]|", options: NSLayoutFormatOptions.init(rawValue: 0), metrics: nil, views: ["customLabel":self.customLabel]))
self.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|-10-[customLabel]-10-|", options: NSLayoutFormatOptions.init(rawValue: 0), metrics: nil, views: ["customLabel":self.customLabel]))
}
}
【讨论】: