UIView状态监视

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状态监视函数



你可能感兴趣的:(UIView状态监视函数,didAddSubview)