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

2016-10-17  本文已影响0人  xwf_code

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是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");
}
上一篇 下一篇

猜你喜欢

热点阅读