Observing changes to a UIView's window and superview properties

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

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

Override this method:

- (void)didMoveToSuperview
{
  UIView *superView = [self superview];
}

And you can override these methods in your custom view for other use:

- (void)willMoveToSuperview:(UIView *)newSuperview;
- (void)didMoveToSuperview;
- (void)willMoveToWindow:(UIWindow *)newWindow;
- (void)didMoveToWindow;

based on the code by @doug-richardson, why not something a little cleaner that will allow KVO for the superview property?

//Make views announce their change of superviews
    Method method = class_getInstanceMethod([UIView class], @selector(willMoveToSuperview:));
    IMP originalImp = method_getImplementation(method);

    void (^block)(id, UIView*) = ^(id _self, UIView* superview) {
        [_self willChangeValueForKey:@"superview"];
        originalImp(_self, @selector(willMoveToSuperview:), superview);
        [_self didChangeValueForKey:@"superview"];
    };

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