• iOS_2022_简单介绍UIViewController&UIView


    UI篇-VC的生命周期以及UIView的layoutSubviews和drawRect方法 ❤️

    一、UIView

    layer上图形绘制见:iOS_2022_CALayer

    layoutSubviews在以下情况下会被调用:

    1、init初始化不会触发layoutSubviews。
    2、addSubview会触发layoutSubviews。
    3、设置view的Frame会触发layoutSubviews,当然前提是frame的值设置前后发生了变化。
    4、滚动一个UIScrollView会触发layoutSubviews。
    5、旋转Screen会触发父UIView上的layoutSubviews事件。
    6、改变一个UIView大小的时候也会触发父UIView上的layoutSubviews事件。
    7、直接调用setLayoutSubviews

    drawRect在以下情况下会被调用:

     1、如果在UIView初始化时没有设置rect大小,将直接导致drawRect不被自动调用。drawRect 掉用是在Controller->loadView, Controller->viewDidLoad 两方法之后掉用的.所以不用担心在 控制器中,这些View的drawRect就开始画了.这样可以在控制器中设置一些值给View(如果这些View draw的时候需要用到某些变量 值).
     2、该方法在调用sizeToFit后被调用,所以可以先调用sizeToFit计算出size。然后系统自动调用drawRect:方法。
     3、通过设置contentMode属性值为UIViewContentModeRedraw。那么将在每次设置或更改frame的时候自动调用drawRect:。
     4、直接调用setNeedsDisplay,或者setNeedsDisplayInRect:触发drawRect:,但是有个前提条件是rect不能为0。以上1,2推荐;而3,4不提倡

    drawRect方法使用注意点:

    1、 **若使用UIView绘图,只能在drawRect:方法中获取相应的contextRef并绘图。如果在其他方法中获取将获取到一个invalidate 的ref并且不能用于画图**。**drawRect:方法不能手动显示调用,必须通过调用setNeedsDisplay 或 者 setNeedsDisplayInRect,让系统自动调该方法。强行调用也不会起作用的。**
    2、**若使用calayer绘图,只能在drawInContext: 中(类似鱼drawRect)绘制**,或者在delegate中的相应方法绘制。同样也是调用setNeedDisplay等间接调用以上方法
    3、**若要实时画图,不能使用gestureRecognizer,只能使用touchbegan等方法来掉用setNeedsDisplay实时刷新屏幕。**

    UIView的setNeedsDisplay和setNeedsLayout方法。

    首先两个方法都是异步执行的。setNeedsDisplay会调用 drawRect方法,这样可以拿到UIGraphicsGetCurrentContext,就可以画画。 setNeedsLayout会默认调用layoutSubViews,就可以处理子视图中的一些数据。

    **综上两个方法都是异步执行的,layoutSubviews方便数据计算,drawRect方便视图重绘。UIView中方法的执行顺序大概是这样的:

    init 方法 >>属性的set/get 方法>> layoutSubviews(当然是要达到触发条件)>>drawRect, 使用得当可以在View的调用中起到很好的效果。

    二、UIViewController

    UIViewController的生命周期详解

    /*

    两种情况下走该方法

    1、主动调用

    2、调用init方法之后

    */

    - (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil;

     

    ViewController是上层视图ViewController1是push过去的二级视图。我们可以看到ViewController1从初始化到释放的整个过程。

    1. + (void)initialize:函数并不会每次创建对象都调用,只有在第一次初始化的时候才会调用,再次创建将不会调用initialize方法。
    2. init方法和initWithCoder方法相似,只是被调用的环境不一样。如果用代码初始化,会调用init方法,从nib文件或者归档(xibstoryboard)进行初始化会调用initWithCoderinitWithCoderNSCoding协议中的方法,NSCoding是负责编码解码,归档处理的协议。
    3. loadView:是开始加载view的起始方法,除非手动调用,否则在ViewController的生命周期中只调用一次。
    4. viewDidLoad:是我们最常用的方法,类成员对象和变量的初始化我们都会放在这个方法中。在创建类后无论视图展现还是消失,这个方法也只会在布局是调用一次。
    5. viewWillAppear:(BOOL)animated:方法 是在视图将要展现出来的时候调用。
    6. viewWillLayoutSubviews:方法是在将要布局子视图的时候调用。
    7. viewDidLayoutSubviews:方法是在子视图布局完成后调用。
    8. viewDidAppear:(BOOL)animated:方法是视图已经出现。
    9. viewWillDisappear:(BOOL)animated:方法是视图即将消失。
    10. viewDidDisappear:(BOOL)animated:视图已经消失。
    11. deallocViewController被释放时调用。

    总结

    从上面的打印我们可以看到ViewController的整个生命周期,从初始化到被释放。其中在退出ViewController控制器的时候可以看到程序会先调用ViewControllerviewWillDisappear:(BOOL)animated方法然后会调用上一级视图的viewWillAppear:(BOOL)animated方法,然后才会调用当前视图的viewDidDisappear:(BOOL)animated方法。

    2019-05-21 09:29:41.532655+0800 ThinTableVIew1[77845:3751647] ========  ViewController1 类初始化方法: initialize   =======
    
    2019-05-21 09:29:41.533321+0800 ThinTableVIew1[77845:3751647] ======== ViewController1  实例初始化方法: init   =======
    
    2019-05-21 09:29:41.539746+0800 ThinTableVIew1[77845:3751647] ======== ViewController1  加载视图: loadView   =======
    
    2019-05-21 09:29:41.539975+0800 ThinTableVIew1[77845:3751647] ========  ViewController1 将要加载视图: viewDidLoad   =======
    
    2019-05-21 09:29:41.540280+0800 ThinTableVIew1[77845:3751647] ========  ViewController1 视图将要出现: viewWillAppear:(BOOL)animated   =======
    
    2019-05-21 09:29:41.581539+0800 ThinTableVIew1[77845:3751647] ======== ViewController1  将要布局子视图: viewWillLayoutSubviews   =======
    
    2019-05-21 09:29:41.581755+0800 ThinTableVIew1[77845:3751647] ======== ViewController1  已经布局子视图: viewDidLayoutSubviews   =======
    
    2019-05-21 09:29:42.086186+0800 ThinTableVIew1[77845:3751647] ======== ViewController1  视图已经出现: viewDidAppear:(BOOL)animated   =======
    
    2019-05-21 09:30:11.567953+0800 ThinTableVIew1[77845:3751647] ======== ViewController1  视图将要消失: viewWillDisappear:(BOOL)animated   =======
    
    2019-05-21 09:30:11.568210+0800 ThinTableVIew1[77845:3751647] ========  ViewController 视图将要出现: viewWillAppear:(BOOL)animated   =======
    
    2019-05-21 09:30:12.074866+0800 ThinTableVIew1[77845:3751647] ======== ViewController1  视图已经消失: viewDidDisappear:(BOOL)animated   =======
    
    2019-05-21 09:30:12.075103+0800 ThinTableVIew1[77845:3751647] ========  ViewController 视图已经出现: viewDidAppear:(BOOL)animated   =======
    
    2019-05-21 09:30:12.075378+0800 ThinTableVIew1[77845:3751647] ========  ViewController1 释放: dealloc   ======= 

    ========================================

           2022/7/22更新----如上

    ========================================

    总结:vc/view 通过sb/xib初始化会走awakeFromNib

    常用:cell通过xib生成,做一些初始化操作

    1、vc通过sb初始化

      initWithCoder    awakeFromNib    loadView    viewDidLoad

    2、vc通过xib初始化

      a、[[类 alloc] initWithNibName:类名字符串 bundle:nil]

      initWithNibName:类名字符串 bundle:nil    loadView    viewDidLoad

      b、[[类 alloc] init]

      init     loadView    viewDidLoad

      c、 [[类 alloc] initWithFrame:]

      initWithFrame    loadView    viewDidLoad

      d、vc未通过xib略

    3、view

      init/initWithFrame    drawRect

    4、cell通过xib

      initWithCoder    awakeFromNib

    loadView    viewDidLoad    viewDidUnload(已弃用)    关系

    1.第一次访问UIViewController的view时,view为nil,然后就会调用loadView方法创建view

    2.view创建完毕后会调用viewDidLoad方法进行界面元素的初始化

    3.当内存警告时,系统可能会释放UIViewController的view,将view赋值为nil,并且调用viewDidUnload(已弃用)方法

    4.当再次访问UIViewController的view时,view已经在3中被赋值为nil,所以又会调用loadView方法重新创建view

    5.view被重新创建完毕后,还是会调用viewDidLoad方法进行界面元素的初始化

      

  • 相关阅读:
    SpringCloud(一)概念及设计
    SpringBoot2(十三)HttpMessageConverter
    SpringBoot2(十二)当Shiro遇上RedisCache
    SpringBoot2(十一)集成RedisCache
    UDP协议解析 以及和TCP协议的区别
    TCP协议解析及相关问题
    mybatis缓存机制
    MYSQL数据库类型与JAVA类型对应表
    Java HashMap问题
    Java数据库事务四大特性以及隔离级别
  • 原文地址:https://www.cnblogs.com/liyonghua/p/8202937.html
Copyright © 2020-2023  润新知