观察对UIView的窗口和Superview属性的更改 [英] Observing changes to a UIView's window and superview properties

查看:71
本文介绍了观察对UIView的窗口和Superview属性的更改的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在寻找一种在可见视图层次结构中添加或删除通用UIView时得到通知的方法.在这种情况下,KVO看起来很完美,但是观察视图的窗口或Superview属性的更改无济于事.对诸如frame或backgroundColor之类的属性的更改可以按预期工作,但是更改为与视图层次结构相关的属性似乎从未调用过watchValueForKeyPath.

I'm looking for a way to be notified when a generic UIView is added or removed from the visible view hierarchy. KVO looked like the perfect thing to use in this case, but observing changes to a view's window or superview properties doesn't do anything. Changes to properties like frame, or backgroundColor work as expected but changed to properties relating to the view hierarchy doesn't seem to ever call observeValueForKeyPath.

我通过自动调用NotifyObserversForKey来检查UIView是否在这些属性上支持KVO,并且UIView都对这两个报告为YES,这让我很茫然.所以我的问题是:

I checked to see if UIView supports KVO on those properties by calling automaticallyNotifiesObserversForKey, and UIView reported YES for both, leaving me at a loss. So my questions are:

1)是否有一种方法可以使用KVO通知与要添加到视图层次结构或从视图层次结构中删除的视图有关的事件?

1) Is there a way to use KVO to be notified of events relating to a view being added/removed to the view hierarchy?

2)如果不是这样,还可以通过另一种方式通知此类事件,而这些事件不涉及对UIView的子类化?

2) If not is there another way to be notified of such events that doesn't involve sub-classing UIView?

推荐答案

这是一种方法.毛重吗?是的.我推荐这种行为吗?不,但是我们都是成年人.

Here is a way. Is it gross? Yes. Do I recommend such behavior? No. But we're all adults here.

要点是,您可以使用method_setImplementation更改-[UIView didAddSubview:]的实现,以便在调用它时得到通知(并且对willRemoveSubview:做相同的事情).不幸的是,您将被要求进行所有视图层次结构更改.您必须添加自己的过滤条件才能找到您感兴趣的特定视图.

The gist is that you use method_setImplementation to change the implementation of -[UIView didAddSubview:] so you get notified whenever it's called (and you'd do the same thing for willRemoveSubview:). Unfortunately, you will get called for all view hierarchy changes. You'll have to add your own filtering to find the specific views you're interested in.

static void InstallAddSubviewListener(void (^listener)(id _self, UIView* subview))
{
    if ( listener == NULL )
    {
        NSLog(@"listener cannot be NULL.");
        return;
    }

    Method addSubviewMethod = class_getInstanceMethod([UIView class], @selector(didAddSubview:));
    IMP originalImp = method_getImplementation(addSubviewMethod);

    void (^block)(id, UIView*) = ^(id _self, UIView* subview) {
        originalImp(_self, @selector(didAddSubview:), subview);
        listener(_self, subview);
    };

    IMP newImp = imp_implementationWithBlock((__bridge void*)block);
    method_setImplementation(addSubviewMethod, newImp);
}

要使用,请执行以下操作:

To use, do something like:

InstallAddSubviewListener(^(id _self, UIView *subview) {
    NSLog(@"-[UIView didAddSubview:]   self=%@, view=%@", _self, subview);
});

这篇关于观察对UIView的窗口和Superview属性的更改的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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