1、自定义MyUIView,使其继承自UIView,并重写状态监视函数,代码如下:
//
// MyUIView.h
#import <UIKit/UIKit.h>
@interface MyUIView : UIView
@end
//
// MyUIView.m
#import "MyUIView.h"
@implementation MyUIView
- (void)didAddSubview:(UIView *)subview {
//有子元素追加在此元素上
NSLog(@"有子元素追加在此元素上");
}
- (void)willRemoveSubview:(UIView *)subview {
NSLog(@"我的子元素即将被删除");
}
- (void)willMoveToSuperview:(UIView *)newSuperview {
//当前UIView作为其他UIView的子元素被追加或者删除前
//就是说此元素被追加到UIView或者UIView的子类定义的元素上
NSLog(@"我作为子元素即将被追加,或者删除");
}
- (void)didMoveToSuperview {
//当前UIView作为其他UIView的子元素被追加或者删除后
NSLog(@"我作为子元素已经被追加,或者删除");
}
- (void)willMoveToWindow:(UIWindow *)newWindow {
//当前UIView作为其他UIWindow的子元素被追加或者删除前
NSLog(@"%s", __func__);
}
- (void) didMoveToWindow {
//当前UIView作为其他UIWindow的子元素被追加或者删除后
NSLog(@"%s", __FUNCTION__);
}
/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
// Drawing code
}
*/
@end
2、测试:
(1)、在APPDelegate中:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
self.window.rootViewController = [[ViewController alloc] init];
MyUIView * view1 = [[MyUIView alloc] initWithFrame:CGRectMake(10, 200, 50, 50)];
[self.window addSubview:view1];
return YES;
}
输出:
2015-11-24 09:33:16.014 07-UIView的状态监视[1035:20261] -[MyUIView willMoveToWindow:]
2015-11-24 09:33:16.015 07-UIView的状态监视[1035:20261] 我作为子元素即将被追加,或者删除
2015-11-24 09:33:16.015 07-UIView的状态监视[1035:20261] -[MyUIView didMoveToWindow]
2015-11-24 09:33:16.015 07-UIView的状态监视[1035:20261] 我作为子元素已经被追加,或者删除
为什么输出四个呢?不是应该只调用那两个window的状态监视函数吗?因为UIWindow继承自UIView
(2)、测试其他状态监视函数:
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.view.backgroundColor = [UIColor whiteColor];
MyUIView * view1 = [[MyUIView alloc] initWithFrame:CGRectMake(100, 100, 50, 50)];
view1.backgroundColor = [UIColor brownColor];
[self.view addSubview:view1];
UIView * view2 = [[UIView alloc] initWithFrame:CGRectMake(10, 10, 20, 20)];
view2.backgroundColor = [UIColor redColor];
[view1 addSubview:view2];
[view2 removeFromSuperview];
}
输出:
2015-11-24 09:33:16.018 07-UIView的状态监视[1035:20261] 我作为子元素即将被追加,或者删除
2015-11-24 09:33:16.019 07-UIView的状态监视[1035:20261] 我作为子元素已经被追加,或者删除
2015-11-24 09:33:16.019 07-UIView的状态监视[1035:20261] 有子元素追加在此元素上
2015-11-24 09:33:16.020 07-UIView的状态监视[1035:20261] 我的子元素即将被删除
2015-11-24 09:33:16.021 07-UIView的状态监视[1035:20261] -[MyUIView willMoveToWindow:]
2015-11-24 09:33:16.021 07-UIView的状态监视[1035:20261] -[MyUIView didMoveToWindow]
这个地方为什么多了两个MoveToWindow呢?
但是如果测试代码中加上将view1也移除,那么:
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.view.backgroundColor = [UIColor whiteColor];
MyUIView * view1 = [[MyUIView alloc] initWithFrame:CGRectMake(100, 100, 50, 50)];
view1.backgroundColor = [UIColor brownColor];
[self.view addSubview:view1];
UIView * view2 = [[UIView alloc] initWithFrame:CGRectMake(10, 10, 20, 20)];
view2.backgroundColor = [UIColor redColor];
[view1 addSubview:view2];
[view2 removeFromSuperview];
[view1 removeFromSuperview];
}
输出:
2015-11-24 09:43:30.739 07-UIView的状态监视[1111:23344] 我作为子元素即将被追加,或者删除
2015-11-24 09:43:30.740 07-UIView的状态监视[1111:23344] 我作为子元素已经被追加,或者删除
2015-11-24 09:43:30.741 07-UIView的状态监视[1111:23344] 有子元素追加在此元素上
2015-11-24 09:43:30.741 07-UIView的状态监视[1111:23344] 我的子元素即将被删除
2015-11-24 09:43:30.742 07-UIView的状态监视[1111:23344] 我作为子元素即将被追加,或者删除
2015-11-24 09:43:30.743 07-UIView的状态监视[1111:23344] 我作为子元素已经被追加,或者删除
显然那两个MoveToWindow函数没有被调用。为什么呢?
下面给出大概原因:
代码改动如下:
//
// ViewController.m
#import "ViewController.h"
#import "MyUIView.h"
@interface ViewController ()
{
MyUIView * view1;
}
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.view.backgroundColor = [UIColor whiteColor];
view1 = [[MyUIView alloc] initWithFrame:CGRectMake(100, 100, 50, 50)];
view1.backgroundColor = [UIColor brownColor];
[self.view addSubview:view1];
UIView * view2 = [[UIView alloc] initWithFrame:CGRectMake(10, 10, 20, 20)];
view2.backgroundColor = [UIColor redColor];
[view1 addSubview:view2];
[view2 removeFromSuperview];
// [view1 removeFromSuperview];
NSLog(@"%s", __FUNCTION__);
NSLog(@"%@", view1.superview);
NSLog(@"%@", view1.superview.superview);
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
NSLog(@"%s", __FUNCTION__);
NSLog(@"%@", view1.superview);
NSLog(@"%@", view1.superview.superview);
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
输出:
2015-11-24 09:49:13.127 07-UIView的状态监视[1176:25140] 我作为子元素即将被追加,或者删除
2015-11-24 09:49:13.127 07-UIView的状态监视[1176:25140] 我作为子元素已经被追加,或者删除
2015-11-24 09:49:13.128 07-UIView的状态监视[1176:25140] 有子元素追加在此元素上
2015-11-24 09:49:13.128 07-UIView的状态监视[1176:25140] 我的子元素即将被删除
2015-11-24 09:49:13.129 07-UIView的状态监视[1176:25140] -[ViewController viewDidLoad]
2015-11-24 09:49:13.130 07-UIView的状态监视[1176:25140] <UIView: 0x7feb22521ff0; frame = (0 0; 414 736); autoresize = W+H; layer = <CALayer: 0x7feb2251ab40>>
2015-11-24 09:49:13.130 07-UIView的状态监视[1176:25140] (null)
2015-11-24 09:49:13.131 07-UIView的状态监视[1176:25140] -[MyUIView willMoveToWindow:]
2015-11-24 09:49:13.132 07-UIView的状态监视[1176:25140] -[MyUIView didMoveToWindow]
2015-11-24 09:49:13.138 07-UIView的状态监视[1176:25140] -[ViewController viewDidAppear:]
2015-11-24 09:49:13.140 07-UIView的状态监视[1176:25140] <UIView: 0x7feb22521ff0; frame = (0 0; 414 736); autoresize = W+H; layer = <CALayer: 0x7feb2251ab40>>
2015-11-24 09:49:13.142 07-UIView的状态监视[1176:25140] <UIWindow: 0x7feb2245fe70; frame = (0 0; 414 736); gestureRecognizers = <NSArray: 0x7feb22460d30>; layer = <UIWindowLayer: 0x7feb2245c750>>
由输出可以看到,当在viewDidLoad中,view1.superview.superview为空,当在viewDidAppear中view1.superview.superview是UIWindow类型,self.view作为子元素追加到了UIWindow上面,所以才会调用两个window状态监视函数