美文网首页
UI高级01-程序的声明周期-操作连线

UI高级01-程序的声明周期-操作连线

作者: xwf_code | 来源:发表于2016-10-17 21:06 被阅读0次

    view控制器是通过懒加载的方式进行加载的,即用到的时候再加载。

    当view视图有连线的控件时 如果view没有加载(self.view==nil) 连线是没有完成的
    需要当视图需要被显示的时候才会加载视图
    因此,此时视图还没有创建出来, 此时连线是没有完成的
    特别注意 如果只是单纯的view 而不是view控制器 那么当加载完成后 连线是已经完成的

    控制器的awakeFromNib执行时, 根视图还没有加载, 所以连线与事件连接都没有效果
    当loadView执行后, 此时连线与事件连接都会生效
    所以如果要操作属性一般建议在viewDidLoad中操作

    loadView方法

    当我们用到控制器view时,就会调用控制器view的get方法,在get方法内部,首先判断view是否已经创建,如果已存在,则直接返回存在的view,如果不存在,则调用控制器的loadView方法,在控制器没有被销毁的情况下,loadView也可能会被执行多次
    如果需要重新该方法 为了自定义根视图, 因此不要执行super
    注意: 将loadView理解成self.view的getter, 因此不要调用getter
    以下是重写的例子

    {
        UIView *view = [[UIView alloc] init];
         [view setBackgroundColor:[UIColor redColor]];
            // 如果自定义根视图, 要将自定义的视图赋值给self.view, 
        //下面是setter方法 不是getter方法 不冲突
         self.view = view;
    };
    

    viewDidLoad方法

    当控制器的loadView方法执行完毕,view被创建成功后,就会执行viewDidLoad方法,该方法与loadView方法一样,也有可能被执行多次。在开发中,我们可能从未遇到过执行多次的情况,那什么时候会执行多次呢?

    比如A控制器push出B控制器,此时,窗口显示的是B控制器的view,此时如果收到内存警告,我们一般会将A控制器中没用的变量及view销毁掉,之后当我们从B控制器pop到A控制器时,就会再次执行A控制器的loadView方法与viewDidLoad方法。

    init 方法会在内存分配(alloc)完成, 初始化(init)该对象
    关于控制器的实例化, 实际上是由 initWithNibname: bundle: 来实现的
    Designated Initializer(指定的构造器, 由该类型的方法来实现类的实例化)

    对于视图控制器而言, 使用init方法来实例化时, 本质上是调用了 initWithNibname: bundle: 来完成的, 两个参数都为nil.(从sb实例时不走该方法,因为需要读取SB文件, 解析, 还原里面保存的对象,详细请看下面3.1示例)

    • 是个默认搜索机制, 先经过搜索, 确认没有与控制器关联的Nib文件后, 两个参数才是nil
    • 搜索机制, 是为确认是否存在与控制器关联的Nib文件
    • 搜索是否存在与控制器类名相同的Xib文件
    • 搜索是否存在"控制器类名, 去掉Controller"的Xib文件

    Nib是Xib的前身, Nib是可执行文件, Xib实际是XML文件 (Xib文件最多与一个控制器关联)
    该XML文件会记录用户的操作, 保存起来, 在运行的时候加载该Xib文件, 解析出对应的对象
    Storybord可以理解成多个Nib, 可以保存多个控制器 (里面会包含多个控制器)
    IB (Interface Builder) (SB|Xib) 图形化的构造器(编辑器)

    通过SB来加载控制器

    1 获取Storyboard

    UIStoryboard *sb = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
    

    2从SB当中, 加载控制器
    2.1 实例化SB文件中, 初始控制器(箭头指向的那个控制器)
    即需要在指定的控制器中确定 storyboard ID

    ViewController *vc = [sb instantiateInitialViewController];
    

    3实例化SB文件中, 指定的控制器 (从多个控制器当中, 根据id找到指定的控制器)

    TestViewController *vc = [sb instantiateViewControllerWithIdentifier:@"TestViewController"];
    

    3.1特别注意特别注意特别注意!

    用纯代码形式而不是从NIB或SB中加载/实例化<视图>控制器时的init方法会调用下面方法

    - (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
    {
        if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
            NSLog(@"方法");
        }
        return self;
    }
    

    **通过Nib(SB)来加载(视图)控制器, 会由该方进行解档 (读取SB文件, 解析, 还原里面保存的对象) **
    归档 (将对象保存成数据)
    解档 (数据还原成对象)

    - (instancetype)initWithCoder:(NSCoder *)aDecoder
    {
        if (self = [super initWithCoder:aDecoder]) {
            
        }
        return self;
    }
    

    当加载完上面的方法 也就是从NIB或sb中加载实例化控制器对象后

    Nib(SB)解档和加载的操作完成后, 会触发该方法
    - (void)awakeFromNib
    {
        NSLog(@"SB文件的加载已经完成");
    }
    

    根视图相关的方法, 随着控制器之间的切换, 会一直触发相应的方法

    ** 根视图即将被显示出来 (显示之前做一些准备)**

    - (void)viewWillAppear:(BOOL)animated
    {
        [super viewWillAppear:animated];
        
        NSLog(@"根视图即将被显示出来");
    }
    

    根视图已经显示出来 (已经看到视图)
    如果这个方法是由第二个视图调用 需要第一个视图已经消失后才会触发

    - (void)viewDidAppear:(BOOL)animated
    {
        [super viewDidAppear:animated];
        
        NSLog(@"根视图已经显示出来");
    }
    

    **根视图即将要消失时触发 (消失之前做一些操作) **

    - (void)viewWillDisappear:(BOOL)animated
    {
        [super viewWillDisappear:animated];
        
        NSLog(@"根视图即将要消失时触发");
    }
    

    根视图已经消失后触发 (不是销毁)
    已经消失的方法 需要下一个视图已经显示 就是下一个视图执行了视图已经显示的方法后 第一个视图的消失后触发的方法才会触发

    - (void)viewDidDisappear:(BOOL)animated
    {
        [super viewDidDisappear:animated];
        
        NSLog(@"根视图已经消失后触发");
    }
    

    视图显示的相关方法 - 父视图相关

    **该view即将移动到某个父视图上 如 self.view addsubview 方法就好调用以下方法 **

    - (void)willMoveToSuperview:(UIView *)newSuperview
    {
        [super willMoveToSuperview:newSuperview];
        
        NSLog(@"即将移动到某个父视图上, %@", newSuperview);
    }
    

    该view已经移动到某个父视图上

    - (void)didMoveToSuperview
    {
        [super didMoveToSuperview];
    }
    

    视图显示的相关方法 - Window相关

    该view即将被移动到某个window上

    - (void)willMoveToWindow:(UIWindow *)newWindow
    {
        [super willMoveToWindow:newWindow];
        
        NSLog(@"moveToWindow: %@", newWindow);
    }
    

    该view已经被移动到某个window上

    - (void)didMoveToWindow
    {
        
    }
    

    控制器的根视图是不用给frame值的
    因为控制器将其改成一样大

    segue连线中的属性

    segue.sourceViewController —>原控制器
    segue.destinationViewController —>将要跳转的控制器
    sender—>触发跳转的控件

    连线常见操作

    // 点击了任何地方, 都会触发该方法
    - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
    {
        /*------ 手动的执行代码, 让Segue进行跳转 ------*/
        
        // 执行指定的ID所对应的Segue (SB当中已经有该IB对应好的Segue)
        [self performSegueWithIdentifier:@"VC2Second" sender:@"我的"];
    }
    
    //Segue跳转前的准备 使用连线跳转的时候会执行的方法
    
    - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
    {
        NSLog(@"asdf");
    }
    

    相关文章

      网友评论

          本文标题:UI高级01-程序的声明周期-操作连线

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