在Swift3中,KVO是UIView的Alpha吗? [英] In Swift3, KVO the alpha of a UIView?

查看:67
本文介绍了在Swift3中,KVO是UIView的Alpha吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用这篇出色的文章中的技术,在Swift3中KVO值很容易.

It's "easy" to KVO a value in Swift3, using the technique in this great post...

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

我如何KVO UIView的Alpha?

How do I KVO the alpha of a UIView?

目标:假设屏幕的视图很小V.屏幕的视图很大.每个单元格都有一个较小的CV视图.

Goal: imagine a screen with a small view V. Screen has a large table view. Each cell has a small view CV.

我希望每个CV都在V的alpha动画期间遵循 1 V的alpha.

I want each CV to follow1 the alpha of V, actually during an animation of the alpha of V.

(我能想到的唯一真正的替代方法是对CADisplayLink单元进行轮询,并轮询V的alpha,这很烂.)

(The only real alternate I can think of is to CADisplayLink the cells and poll the alpha of V, which kind of sucks.)

1 是这个原因吗?这是跨单元同步Alpha更改的唯一方法.

1Reason for that? It's the only way to sync alpha changes across cells.

注意,就像Rob在下面解释的那样,实际上图层的Alpha不会设置动画. (它只是在动画开始时将立即"设置为新值.)实际上,您必须遵循表示层.这是一个逆过程的示例,它可以从您希望每次抽奖的位置拉出

Note Just as Rob explains below, in fact the alpha of a layer does not animate. (It just sets "instantly" to the new value at the beginning of an animation.) In fact you have to follow the presentation layer. Here's an example of the converse process, pulling it from where you want every draw

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
  }

推荐答案

这不是KVO的理想用例.您可能更喜欢转到更改alpha的代码,并使其对其他视图进行必要的更新(或构建一些接口以更一般地执行该操作;而不是KVO).

This is not an ideal use-case of KVO. You'd probably prefer to go to the code that is changing the alpha and have it do the necessary updates of the other views (or build some interface to do that more generically; something other than KVO).

还请注意,如果您正在处理动画,则alpha的KVO可能仅标识动画的启动,而不观察动画过程中的变化. (通常用CADisplayLink等中的presentation/presentationLayer捕获这些类型的更改.)

Also note that if you're dealing with animations, the KVO of alpha may only identify the initiation of the animation, not observing the changes mid-flight during the animation. (Those sorts of changes are generally captured with the presentation/presentationLayer in a CADisplayLink or the like.)

话虽如此,是的,您可以观察alpha属性.因此,在Swift 3中,只需定义上下文即可:

Having said that, yes, you can observe alpha property. So, in Swift 3, just define context:

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中完成该操作:

Note, remember to remove the observer. For example, you might do that in deinit:

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


请注意,在Swift 4中,此过程有所简化.定义一个token属性以跟踪您的观察者:


Note, in Swift 4, this process is simplified a bit. Define a token property to keep track of your observer:

private var token: NSKeyValueObservation?

然后观察alpha属性:

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

请注意,使用[weak self]可以确保闭包不会引起较强的引用周期.显然,如果您在该闭包中未引用self,则不需要.

Note the use of [weak self] to ensure the closure doesn't cause strong reference cycle. Obviously, if you're not referencing self in that closure, that is not needed.

但是基于块的模式的优点是:(a)当token超出范围时,观察者将被自动删除,因此不需要特殊的deinit例程; (b)现在已严格键入observedView的可观察键,避免了键中的简单印刷错误; (c)由于观察者已链接到此闭包,因此我们不再需要对观察者的上下文进行检查,如果不是我们的上下文,则调用self.

But the virtue of the block based pattern is that (a) when the the token falls out of scope, the observer is automatically removed, so no special deinit routine is needed; (b) the observable keys for observedView are now strongly typed, avoiding simple typographical errors in the keys; and (c) because the observer is linked to this closure, we no longer have to do that check of the context of the observer and call self if this wasn't our context.

这篇关于在Swift3中,KVO是UIView的Alpha吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆