美文网首页
iOS--UIView

iOS--UIView

作者: mayuee | 来源:发表于2020-07-17 17:46 被阅读0次

UIView生命周期

新建一个继承UIView的视图SView,在.m文件实现

@implementation SView

- (void)awakeFromNib

{

    [super awakeFromNib];

    NSLog(@"%@____________%@", @(_count++), NSStringFromSelector(_cmd));

}

- (instancetype)initWithCoder:(NSCoder*)coder

{

    if(self= [superinitWithCoder:coder]) {

        NSLog(@"%@____________%@", @(_count++), NSStringFromSelector(_cmd));

    }

    return self;

}

- (instancetype)initWithFrame:(CGRect)frame

{

    if(self= [superinitWithFrame:frame]) {

        NSLog(@"%@____________%@_______%@", @(_count++), NSStringFromSelector(_cmd), NSStringFromCGRect(frame));

    }

    return self;

}

- (instancetype)init {

    self= [superinit];

    if(self) {

        NSLog(@"%@____________%@", @(_count++), NSStringFromSelector(_cmd));

    }

    return self;

}

- (void)layoutSubviews {

    [super layoutSubviews];

    NSLog(@"%@____________%@", @(_count++), NSStringFromSelector(_cmd));

}

- (void)didAddSubview:(UIView*)subview {

    [superdidAddSubview:subview];

    NSLog(@"%@____________%@________%@", @(_count++), NSStringFromSelector(_cmd), subview);

}

- (void)willRemoveSubview:(UIView*)subview {

    [super willRemoveSubview:subview];

    NSLog(@"%@____________%@________%@", @(_count++), NSStringFromSelector(_cmd), subview);

}

- (void)willMoveToSuperview:(nullableUIView*)newSuperview {

    [superwillMoveToSuperview:newSuperview];

    NSLog(@"%@____________%@________%@",@(_count++),NSStringFromSelector(_cmd), newSuperview);

}

- (void)didMoveToSuperview {

    [super didMoveToSuperview];

    NSLog(@"%@____________%@", @(_count++), NSStringFromSelector(_cmd));

}

- (void)willMoveToWindow:(nullableUIWindow*)newWindow {

    [superwillMoveToWindow:newWindow];

    NSLog(@"%@____________%@_______%@", @(_count++), NSStringFromSelector(_cmd), newWindow);

}

- (void)didMoveToWindow {

    [super didMoveToWindow];

    NSLog(@"%@____________%@", @(_count++), NSStringFromSelector(_cmd));

}

- (void)removeFromSuperview {

    [super removeFromSuperview];

    NSLog(@"%@____________%@", @(_count++), NSStringFromSelector(_cmd));

}

- (void)dealloc {

    NSLog(@"%@____________%@", @(_count++), NSStringFromSelector(_cmd));

}

运行代码:

- (void)removeSview

{

     NSLog(@"\n---------————————————————————销毁——————\n");

    [self.sView removeFromSuperview];

    self.sView=nil;

}

- (void)viewDidLoad {

    [super viewDidLoad];

    NSLog(@"\n---------————————————————————创建——————\n");

    self.sView= [[SViewalloc]init];

    [self.view addSubview:self.sView];

    [self performSelector:@selector(removeSview) withObject:nil afterDelay:5];

}

运行结果:

2020-07-17 17:25:11.166846+0800 Test[21054:3473399] ---------————————————————————创建——————

0____________initWithFrame:_______{{0, 0}, {0, 0}}

1____________init

2____________willMoveToSuperview:________<UIView: 0x7fd7adc10940; frame = (0 0; 414 896); autoresize = W+H; layer = <CALayer: 0x600000af2bc0>>

3____________didMoveToSuperview

4____________willMoveToWindow:_______<UIWindow: 0x7fd7aea09830; frame = (0 0; 414 896); gestureRecognizers = <NSArray: 0x600000496d90>; layer = <UIWindowLayer: 0x600000af5400>>

5____________didMoveToWindow

6____________layoutSubviews

---------————————————————————销毁——————

7____________willMoveToSuperview:________(null)

8____________willMoveToWindow:_______(null)

9____________didMoveToWindow

10____________didMoveToSuperview

11____________removeFromSuperview

12____________dealloc

给sView添加一个子视图

[self.sView addSubview:[[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)]];

重新运行,运行结果:

2020-07-17 17:31:13.150901+0800 Test[21249:3477510] 

---------————————————————————创建——————

0____________initWithFrame:_______{{0, 0}, {0, 0}}

1____________init

2____________didAddSubview:________<UIView: 0x7fd67340d6c0; frame = (0 0; 10 10); layer = <CALayer: 0x600003d9a640>>

3____________willMoveToSuperview:________<UIView: 0x7fd67340d960; frame = (0 0; 414 896); autoresize = W+H; layer = <CALayer: 0x600003d9a5e0>>

4____________didMoveToSuperview

5____________willMoveToWindow:_______<UIWindow: 0x7fd67420e750; frame = (0 0; 414 896); gestureRecognizers = <NSArray: 0x6000033e5d40>; layer = <UIWindowLayer: 0x600003d9c8c0>>

6____________didMoveToWindow

7____________layoutSubviews

8____________layoutSubviews

---------————————————————————销毁——————

9____________willMoveToSuperview:________(null)

10____________willMoveToWindow:_______(null)

11____________didMoveToWindow

12____________didMoveToSuperview

13____________removeFromSuperview

 14____________dealloc

15____________willRemoveSubview:________<UIView: 0x7fd67340d6c0; frame = (0 0; 10 10); layer = <CALayer: 0x600003d9a640>>

1、虽然调用init初始化,但是init会先调用initWithFrame:并默认frame为CGRectZero

2、给UIView添加子视图才会调用didAddSubview:和willRemoveSubview:方法,willRemoveSubview:方法是在dealloc后面执行的。如果有多个子视图,willRemoveSubview:会循环执行,直到移除所有子视图

3、添加子视图会调用layoutSubviews

4、添加和销毁都会调用- (void)willMoveToSuperview:(nullable UIView *)newSuperview 和- (void)willMoveToWindow:(nullable UIWindow *)newWindow,可以根据参数判断,nil则为销毁,否则为创建

5、- (void)didMoveToSuperview 和- (void)didMoveToWindow,可以根据self.superview判断,nil则为销毁,否则为创建

6、removeFromSuperview、dealloc两个方法(layoutSubviews在子视图布局变动时会多次调用)只执行了一次,所以可以在这两个方法中执行释放内存等操作(移除观察者,定时器等)。

exp:

如果在initWithFrame中有view的初始化相关操作,layoutSubviews会调用两次。layoutSubviews只进行布局相关处理,不能有view初始化操作(当子视图布局改变时会调用,能多次调用),下面是layoutSubviews的触发条件:

1、init初始化不会触发layoutSubviews,但是用initWithFrame进行初始化时,当rect的值不为CGRectZero时,也会触发。

2、addSubview会触发layoutSubviews。

3、设置UIView的Frame会触发layoutSubviews,当然前提是frame的值设置前后发生了变化。

4、滚动一个UIScrollView会触发layoutSubviews。

5、旋转Screen会触发父UIView上的layoutSubviews。

6、改变一个UIView大小的时候也会触发父UIView上的layoutSubviews。

7、直接调用setLayoutSubviews。

UIView的绘制原理

当UIView调用setNeedDisplay之后,系统会调用view对应layer的 setNeedsDisplay,在当前runloop即将结束的时候调用CALayer的display方法。

CALayer的display方法的内部实现,首先会判断layer的delegete是否响应display方法,如果代理不响应就会进入到系统的绘制流程当中,如果响应,实际上就为我们提供了异步绘制的接口,这样就构成了UIView的绘制原理

系统绘制流程:

CALayer会在内部创建一个backing store(CGContextRef),我们一般在drawRect中可以通过上下文堆栈当中拿到当前栈顶的context。然后layer判断是否有代理,如果没有代理会调用layer的drawInContext方法,如果实现了代理就会调用delegete的drawLayer:inContext方法,这是在发生在系统内部当中的,然后在合适的时机给予回调方法,也就是View的drawRect方法。可以通过drawRect方法做一些其他的绘制工作。然后无论哪两个分支,都由CALayer上传backing store(最终的位图)到CPU。然后结束系统的绘制流程。

异步绘制流程:

借用系统给开的这个口子,即[layer.delegate displayLayer:] 

在这个异步绘制过程中就需要代理负责生成对应的bitmap(位图) 

同时设置bitmap作为layer.contents属性的值

相关文章

  • iOS--UIView

    UIView生命周期 新建一个继承UIView的视图SView,在.m文件实现 @implementation S...

  • iOS--UIView动画

    一、UIView动画 1、基础动画 //标记动画块开始 [UIView beginAnimations:nil c...

  • iOS--UIView与UIViewController

    一、UIViwe基本概念 1、iPhone上看到的控件大部分都是UIView的子类 2、UIView的三个作用 布...

  • IOS--UIView中的坐标转换

    // 将像素point由point所在视图转换到目标视图view中,返回在目标视图view中的像素值-(CGPoi...

网友评论

      本文标题:iOS--UIView

      本文链接:https://www.haomeiwen.com/subject/xhtnhktx.html