NSLayoutConstraint使用self作为Swift 1.2中UIView子类中的项目

时间:2015-04-09 14:45:00

标签: ios iphone swift initialization nslayoutconstraint

我有一个UIView的子类,它使用一些使用Swift声明为ivars的NSLayoutConstraint实例。他们成为ivars的原因是我改变了常数值。其中一个与自我有关:

NSLayoutConstraint(item: self.contentView, attribute: .Right, 
                   relatedBy: .Equal, toItem: self, attribute: .Right, 
                   multiplier: 1, constant: self.contentViewWidth)

如您所知,所有ivars都应该在调用超类init之前初始化,但是只有在超类init之后才能引用self。此外,在初始化NSLayoutConstraint实例后,您无法更改toItem(第二项)值。

在Swift 1.2之前标记带有感叹号的ivar(隐式展开的值)告诉编译器你需要负责这个ivar是非零的,所以你可以在任何你想要的地方初始化ivar直到你确保在调用该代码之前不会使用它。这就是我使用的:我在super.init调用之后隐式解包并初始化了这个NSLayoutConstraint,因此可以引用self:

class FilterView: UIView, UITableViewDelegate, UITableViewDataSource {

    private let contentRightConstraint : NSLayoutConstraint!

    init(frame: CGRect, customMode: Bool = false) {
        super.init(frame: CGRectZero)
        contentRightConstraint = NSLayoutConstraint(item: self.contentView, 
        attribute: .Right, relatedBy: .Equal, toItem: self, 
        attribute: .Right, multiplier: 1, constant: self.contentViewWidth)
    }
}

自Swift 1.2以来,上述解决方案不再适用。我找到了两个解决方法:

1)将let替换为var并使用虚拟值:

class FilterView: UIView, UITableViewDelegate, UITableViewDataSource {

    private var contentRightConstraint = NSLayoutConstraint()

    init(frame: CGRect, customMode: Bool = false) {
    super.init(frame: CGRectZero)
    contentRightConstraint = NSLayoutConstraint(item: self.contentView, 
        attribute: .Right, relatedBy: .Equal, toItem: self, 
        attribute: .Right, multiplier: 1, constant: self.contentViewWidth)
    }
}

这不好,因为它使ivar变化并创建了一个不必要的实例。

2)使用懒惰的var:

class FilterView: UIView, UITableViewDelegate, UITableViewDataSource {

    private lazy var contentRightConstraint : NSLayoutConstraint = 
        NSLayoutConstraint(item: self.contentView, attribute: .Right, 
        relatedBy: .Equal, toItem: self, attribute: .Right, 
        multiplier: 1, constant: self.contentViewWidth)
}

这样做会更好,但仍然可以更改let

有人有其他想法吗?

0 个答案:

没有答案