美文网首页
控制器加载底层原理和UI初始化过程

控制器加载底层原理和UI初始化过程

作者: 前年的邂逅_Jerry | 来源:发表于2017-03-19 22:47 被阅读121次

    1、带xib控制器加载过程

    @implementation ViewController
    - (void)viewDidLoad {
        [super viewDidLoad];
    }
    - (IBAction)btnClicked:(UIButton *)sender {
        //如果只执行init,它会执行initWithNibName:bundle:方法,并且参数都为空
        EOCViewController * vc = [[EOCViewController alloc] init];
        //当nibName参数为nil,表示加载名为EOCViewController的对象,如果bundle为空,表示在主路径下寻找xib文件
        //EOCViewController * vc = [[EOCViewController alloc] initWithNibName:@"EOCViewController" bundle:nil];
        [self presentViewController:vc animated:YES completion:^{
            
        }];
    }
    @end
    
    @implementation EOCViewController
    - (instancetype)init{
        NSLog(@"%s",__func__);
        self = [super init];
        return self;
    }
    - (instancetype)initWithCoder:(NSCoder *)aDecoder{
        NSLog(@"%s",__func__);
        self = [super initWithCoder:aDecoder];
        return self;
    }
    - (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil{
       NSLog(@"%s",__func__);
        self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
        return self;
    }
    @end
    

    结果:

    -[EOCViewController init]
    -[EOCViewController initWithNibName:bundle:]
    -[EOCViewController viewDidLoad]
    

    2、带xib文件,重写loadView方法。不会加载出来这个xib文件。如果不重写这个loadView方法,加载xib的时候会自动加载此方法。如:EOCViewController控制器。

    - (void)loadView{
        NSLog(@"%s",__func__);
        [super loadView];
    }
    

    3、如果去掉EOCViewController控制器的xib文件,执行如下代码:

    - (void)loadView{
        NSLog(@"%s",__func__);
    //    [super loadView];
    }
    - (void)viewDidLoad {
        [super viewDidLoad];
        NSLog(@"%s",__func__);
        self.view.backgroundColor = [UIColor whiteColor];
    }
    

    会造成loadView与viewDidLoad方法循环调用。原因是self.view是懒加载方法:

    - (UIView *)view{
        if (!_view) {
            [self loadView];
            [self viewDidLoad];
        }
        return _view;
    }
    

    4、在xib中加载视图控制器,self.view是在viewDidAppear中加载完的(frame为屏幕的大小),而不是在viewDidLoad中加载完的(frame为xib的大小),所以self.viewframe大小还没有在viewDidLoad中成型。
    不带xib的控制器被加载,viewDidLoad方法中frame的为手机屏幕的大小。
    5、通过重写loadView改变控制器的视图.

    - (void)loadView{
        NSLog(@"%s",__func__);
        [super loadView];
        self.view = [[NSBundle mainBundle] loadNibNamed:@"EOCView" owner:self options:nil].lastObject;
    }
    - (void)viewDidLoad {
        [super viewDidLoad];
        NSLog(@"%s",__func__);
        self.view.backgroundColor = [UIColor whiteColor];
    }
    

    6、视图加载过程
    EOCView * view = [[NSBundle mainBundle]loadNibNamed:@"EOCView" owner:self options:nil].lastObject;启动过程:

    initWithCoder:
    awakeFromNib:
    

    EOCView * view = [[EOCView alloc] init];启动过程:

    init
    initWithFrame:
    

    init方法中会封装initWithFrame:方法。
    7、在initWithFrame:方法中添加视图。

    #import "ECOLabel.h"
    @implementation ECOLabel
    - (instancetype)initWithFrame:(CGRect)frame{
        self = [super initWithFrame:frame];
        if (self) {
            UIView * view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 20, 20)];
            
            view.backgroundColor = [UIColor blueColor];
            [self addSubview:view];
        }
        return self;
    }
    @end
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        self.view.backgroundColor = [UIColor lightGrayColor];
        ECOLabel * lbl = [[ECOLabel alloc] initWithFrame:CGRectMake(0, 0, 90, 90)];
        lbl.backgroundColor = [UIColor yellowColor];
    //    lbl.backgroundColor = [UIColor clearColor];
        [self.view addSubview:lbl];
    }
    

    会出现如下如图一效果:

    ECOLabel对象背景色为黄色 图一.png
    如果将lbl对象的背景色设置成透明色lbl.backgroundColor = [UIColor clearColor];,如图二所示:
    ECOLabel对象背景色为透明色 图二.png
    原因:在执行完initWithFrame:后,视图才会创建完。打断点打印self.layer.sublayers的值。
    7、layoutSubviews
    frame 变化、scrollView、子类view frame发生改变和addSubview都会导致layoutSubviews被动执行。
    8、drawRect
    frame发生变化,drawRect被动执行。添加子View,不调用drawRect方法。因为子View的Frame没发生改变。
    9、xib可视化
    在EOCView类中加入IB_DESIGNABLE 和IBInspectable。
    IB_DESIGNABLE
    @interface EOCView ()
    @property (nonatomic, strong) IBInspectable UIColor * pathColor;
    @property (nonatomic, assign) IBInspectable CGFloat pathWith;
    @end
    
    - (void)drawRect:(CGRect)rect{
        [super drawRect:rect];
        CGFloat centerX = (self.bounds.size.width - self.bounds.origin.x) / 2;
        CGFloat centerY = (self.bounds.size.height - self.bounds.origin.y) / 2;
        
        UIBezierPath * path = [[UIBezierPath alloc] init];
        //添加一个圆形
        [path addArcWithCenter:CGPointMake(centerX, centerY) radius:50 startAngle:0 endAngle:360 clockwise:YES];
        //设置宽度
        path.lineWidth = self.pathWith;
        //设置线条颜色
        [self.pathColor setStroke];
        //绘制线条
        [path stroke];
    }
    

    效果如图三所示。

    视图关联EOCView对象加入控制器的XIB中 图三.png

    相关文章

      网友评论

          本文标题:控制器加载底层原理和UI初始化过程

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