如何进行键值观察并在 UIView 的框架上获得 KVO 回调? [英] How can I do Key Value Observing and get a KVO callback on a UIView's frame?

查看:24
本文介绍了如何进行键值观察并在 UIView 的框架上获得 KVO 回调?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想观察 UIViewframeboundscenter 属性的变化.我如何使用键值观察来实现这一点?

I want to watch for changes in a UIView's frame, bounds or center property. How can I use Key-Value Observing to achieve this?

推荐答案

通常存在不支持 KVO 的通知或其他可观察事件.即使文档说'不',观察支持 UIView 的 CALayer 表面上是安全的.观察 CALayer 在实践中是有效的,因为它广泛使用了 KVO 和适当的访问器(而不是 ivar 操作).不能保证它会继续工作.

There are usually notifications or other observable events where KVO isn't supported. Even though the docs says 'no', it is ostensibly safe to observe the CALayer backing the UIView. Observing the CALayer works in practice because of its extensive use of KVO and proper accessors (instead of ivar manipulation). It's not guaranteed to work going forward.

无论如何,视图的框架只是其他属性的产物.因此,我们需要观察那些:

Anyway, the view's frame is just the product of other properties. Therefore we need to observe those:

[self.view addObserver:self forKeyPath:@"frame" options:0 context:NULL];
[self.view.layer addObserver:self forKeyPath:@"bounds" options:0 context:NULL];
[self.view.layer addObserver:self forKeyPath:@"transform" options:0 context:NULL];
[self.view.layer addObserver:self forKeyPath:@"position" options:0 context:NULL];
[self.view.layer addObserver:self forKeyPath:@"zPosition" options:0 context:NULL];
[self.view.layer addObserver:self forKeyPath:@"anchorPoint" options:0 context:NULL];
[self.view.layer addObserver:self forKeyPath:@"anchorPointZ" options:0 context:NULL];
[self.view.layer addObserver:self forKeyPath:@"frame" options:0 context:NULL];

在此处查看完整示例https://gist.github.com/hfossli/7234623

注意:文档中不支持此功能,但截至今天为止,它适用于所有 iOS 版本(当前为 iOS 2 -> iOS 11)

NOTE: This is not said to be supported in the docs, but it works as of today with all iOS versions this far (currently iOS 2 -> iOS 11)

注意:请注意,在其最终值稳定之前,您将收到多个回调.例如,更改视图或图层的框架将导致图层更改 positionbounds(按此顺序).

NOTE: Be aware that you will receive multiple callbacks before it settles at its final value. For example changing the frame of a view or layer will cause the layer to change position and bounds (in that order).

有了 ReactiveCocoa,你可以做到

With ReactiveCocoa you can do

RACSignal *signal = [RACSignal merge:@[
  RACObserve(view, frame),
  RACObserve(view, layer.bounds),
  RACObserve(view, layer.transform),
  RACObserve(view, layer.position),
  RACObserve(view, layer.zPosition),
  RACObserve(view, layer.anchorPoint),
  RACObserve(view, layer.anchorPointZ),
  RACObserve(view, layer.frame),
  ]];

[signal subscribeNext:^(id x) {
    NSLog(@"View probably changed its geometry");
}];

如果你只想知道 bounds 何时改变,你可以这样做

And if you only want to know when bounds changes you can do

@weakify(view);
RACSignal *boundsChanged = [[signal map:^id(id value) {
    @strongify(view);
    return [NSValue valueWithCGRect:view.bounds];
}] distinctUntilChanged];

[boundsChanged subscribeNext:^(id ignore) {
    NSLog(@"View bounds changed its geometry");
}];

如果你只想知道 frame 什么时候改变,你可以做

And if you only want to know when frame changes you can do

@weakify(view);
RACSignal *frameChanged = [[signal map:^id(id value) {
    @strongify(view);
    return [NSValue valueWithCGRect:view.frame];
}] distinctUntilChanged];

[frameChanged subscribeNext:^(id ignore) {
    NSLog(@"View frame changed its geometry");
}];

这篇关于如何进行键值观察并在 UIView 的框架上获得 KVO 回调?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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