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

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

问题描述

我想留意 UIView 框架界限中心属性。我如何使用键值观察来实现这一目标?

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不通知的通知或其他可观察事件支持的。即使文档说'no',观察CALayer支持UIView表面上也是安全的。观察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

See full example here 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)

注意:请注意你将在结算到最终值之前接收多个回调。例如,更改视图或图层的框架将导致图层更改 position bounds (按此顺序) 。

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");
}];

如果您只想知道何时界限你可以做的改变

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的框架上进行Key Value Observing并获得KVO回调?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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