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] 我作为子元素已经被追加,或者删除
下面给出大概原因:
代码改动如下:
// // 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状态监视函数