2016-12-27 58 views
2

这是“容易” KVO在Swift3,值使用的技术在这个伟大的职位...在Swift3中,KVO是UIView的alpha?

https://stackoverflow.com/a/25219216/294884

如何KVO一个UIView的阿尔法?

目标:想象一个小视图的屏幕V.屏幕有一个大的桌子视图。每个单元格都有一个小视图CV。

我希望每个CV跟随V的阿尔法

(唯一的真正替代我能想到的是CADisplayLink细胞和轮询的α在动画期间 V的α,实际上V,其中种吸。)


原因为何?这是跨单元同步alpha变化的唯一方法。


注意正如下面罗布解释说,其实层的阿尔法并不动画。 (它只是在动画开始时将“即时”设置为新值。)实际上,您必须遵循表示层。这里是一个逆向过程的例子,将它从你想要的每一个凹点拉出来

let d = CADisplayLink(target: self, selector: #selector(ThisClassName.updateAlpha)) 
d.add(to: RunLoop.current, forMode: RunLoopMode.commonModes) 

func updateAlpha() { 
    let a = leader.layer.presentation()?.value(forKey: "opacity") as! CGFloat 
    follower.alpha = a 
    } 

回答

4

这不是一个理想的KVO用例。你可能更愿意去改变alpha的代码,并让它对其他视图进行必要的更新(或者构建一些更通用的界面;除了KVO之外)。

另请注意,如果您正在处理动画,则alpha的KVO可能只能识别动画的开始,而不会观察动画过程中的变化。 (这些变化通常在presentation/,CADisplayLink等中被捕获。)

话虽如此,是的,你可以观察到alpha属性。所以,在斯威夫特3,只是定义背景:

private var observerContext = 0 

然后添加观察员:

observedView.addObserver(self, forKeyPath: "alpha", options: .new, context: &observerContext) 

,然后实现你的观察:

override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) { 
    guard context == &observerContext else { 
     super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context) 
     return 
    } 

    // do what you want here 
} 

注意,记得删除观察者。例如,你可以这样做,在deinit

deinit { 
    observedView.removeObserver(self, forKeyPath: "alpha", context: &observerContext) 
} 

注意,在斯威夫特4,这个过程被简化了一点。定义一个token属性,让您的观察者的轨迹:

private var token: NSKeyValueObservation? 

然后观察alpha属性:

token = observedView.observe(\.alpha) { [weak self] object, change in 
    // do something 
} 

注意使用[weak self],以确保关闭时并不会引起强烈的参考周期。显然,如果你没有在封闭中引用self,那就不需要了。

但是基于块的模式的优点在于(a)当token超出范围时,观察者被自动移除,因此不需要特殊的例程deinit; (b)observedView的可观察键现在是强类型的,从而避免了键中的简单印刷错误;和(c)因为观察员与这一封闭有关,我们不再需要对观察员的背景进行检查,并且如果这不是我们的背景,请致电self

+0

宏伟!当然,它是'forKeyPath:“alpha”'。非常感谢。 – Fattie