使用Swift 3 #keyPath引用UIView子类.center

时间:2018-05-31 04:36:55

标签: ios swift uiview key-value-observing

在我的应用中的视图控制器中,我通过键值观察其center属性来对视图定位的更改作出反应,如下所示:

class CoordinatingViewController: UIViewController {

    @IBOutlet weak var cardContainerView: CardView!

    override func viewDidLoad() {
         super.viewDidLoad()
         addObserver(self, forKeyPath: "cardContainerView.center", options: [.new], context: nil)
    }
}

现在这个工作正常,但由于该键路径是一个字符串,因此编译器无法检查它。为了缓解这种情况,我想使用Swift 3的#keyPath()语法,它采用编译器检查的密钥路径并返回正确的相应字符串。但是,当我更改该行以使用它时:

addObserver(self, forKeyPath: #keyPath(cardContainerView.center), options: [.new], context: nil)

编译器给出了2个错误:

  
      
  1. 键入' CardView!'没有会员'中心'
  2.   
  3. 不能引用类型成员' center'在类型' CardView!'
  4. 的实例中   

我不明白为什么我会收到这些错误,因为centerUIView的文档属性,CardView直接继承,我可以在那里#keyPath()语句之外读写。此外,当我直接将键路径作为字符串传递时,一切似乎都能正常工作,就像在我的第一个例子中一样,这使得这更加令人困惑。如何让编译器为我检查该关键路径?

1 个答案:

答案 0 :(得分:1)

似乎Swift对weak修饰符并不满意。删除它,代码将编译。从this开始,我们可以看到,除非您确实有一个保留周期,否则建议网点很强。有关如何查找保留周期的信息,请参阅我的回答here

在Swift 4中,您将能够使用新的\密钥路径语法执行此操作:

// no problems with "weak"!
let observation = observe(\.cardContainerView.center) { (object, change) in
    ...
}