美文网首页
视图控制器

视图控制器

作者: Grt婷 | 来源:发表于2016-11-22 20:17 被阅读0次

视图控制器

1. 为什么要有视图控制器

  • 我们开发中,可能会遇到某个界面比较复杂,要进行多个界面的切换,如果把这些界面切换全都放在该界面中,控制器代码非常臃肿不说,控制起来也比较麻烦,这个时候我建议用不同的控制器来表示不同的界面,然后将这些界面通过addChildViewController添加到控制器的子控制器中,然后通过系统提供的方法进行切换。

2. 视图控制器的生命周期

  • 当一个视图控制器被创建,并在屏幕上显示的时候。 代码的执行顺序
```c
1、 alloc                                   创建对象,分配空间

2、init (initWithNibName) 初始化对象,初始化数据
3、loadView 从nib载入视图 ,通常这 一步不需要去干涉。除非你没有使用xib文件创建视图
4、viewDidLoad 载入完成,可以进行自定义数据以及动态创建其他控件
5、viewWillAppear 视图将出现在屏幕之前,马上这个视图就会被展现在屏幕上了
6、viewDidAppear 视图已在屏幕上渲染完成
当一个视图被移除屏幕并且销毁的时候的执行顺序,这个顺序差不多和上面的相反
1、viewWillDisappear 视图将被从屏幕上移除之前执行
2、viewDidDisappear 视图已经被从屏幕上移除,用户看不到这个视图了
3、deainit 视图被销毁,此处需要对你在init和viewDidLoad中创建的对象进行释放

```

* 当我们创建一个UIViewController类的对象时,通常系统会生成几个默认的方法,这些方法大多与视图的调用有关,但是在视图调用时,这些方法的调用顺序如何,需要整理下。

通常上述方法包括如下几种,这些方法都是UIViewController类的方法:

```c
-(void)viewDidLoad;
-(void)viewDidUnload;
-(void)viewWillAppear:(BOOL)animated;
-(void)viewDidAppear:(BOOL)animated;
-(void)viewWillDisappear:(BOOL)animated;
-(void)viewDidDisappear:(BOOL)animated;
```

3. 生命周期的每个方法干什么用

下面介绍下APP在运行时的调用顺序。

  • 1)- (void)viewDidLoad;

    一个APP在载入时会先通过调用loadView方法或者载入IB中创建的 初始界面的方法,将视图载入到内存中。然后会调用viewDidLoad方法来进行进一步的设置。通常,我们对于各种初始数据的载入,初始设定等很多内容,都会在这个方法中实现,所以这个方法是一个很常用,很重要的方法。

    但是要注意,这个方法只会在APP刚开始加载的时候调用一次,以后都不会再调用它了,所以只能用来做初始设置。

      • (void)viewDidUnload;

        在内存足够的情况下,软件的视图通常会一直保存在内存中,但是如果内存不够,一些没有正在显示的viewcontroller就会收到内存不够的警告,然后就会释放自己拥有的视图,以达到释放内存的目的。但是系统只会释放内存,并不会释放对象的所有权,所以通常我们需要在这里将不需要在内存中保留的对象释放所有权,也就是将其指针置为nil。

        这个方法通常并不会在视图变换的时候被调用,而只会在系统退出或者收到内存警告的时候才会被调用。但是由于我们需要保证在收到内存警告的时候能够对其作出反应,所以这个方法通常我们都需要去实现。
        另外,即使在设备上按了Home键之后,系统也不一定会调用这个方法,因为IOS4之后,系统允许将APP在后台挂起,并将其继续滞留在内存中,因此,viewcontroller并不会调用这个方法来清除内存。
  • 3)- (void)viewWillAppear:(BOOL)animated;

    系统在载入所有数据后,将会在屏幕上显示视图,这时会先调用这个方法。通常我们会利用这个方法,对即将显示的视图做进一步的设置。例如,我们可以利用这个方法来设置设备不同方向时该如何显示。
    另外一方面,当APP有多个视图时,在视图间切换时,并不会再次载入viewDidLoad方法,所以如果在调入视图时,需要对数据做更新,就只能在这个方法内实现了。所以这个方法也非常常用。

      • (void)viewDidAppear:(BOOL)animated;

        有时候,由于一些特殊的原因,我们不能在viewWillApper方法里,对视图进行更新。那么可以重写这个方法,在这里对正在显示的视图进行进一步的设置。
      • (void)viewWillDisappear:(BOOL)animated;

        在视图变换时,当前视图在即将被移除、或者被覆盖时,会调用这个方法进行一些善后的处理和设置。
        由于在IOS4之后,系统允许将APP在后台挂起,所以在按了Home键之后,系统并不会调用这个方法,因为就这个APP本身而言,APP显示的view,仍是挂起时候的view,所以并不会调用这个方法。
      • (void)viewDidDisappear:(BOOL)animated;

        我们可以重写这个方法,对已经消失,或者被覆盖,或者已经隐藏了 的视图做一些其他操作。

4.模态推出

  //模态推出下一个界面,一般用于注册
        let vc = SecondViewController()
        //1.要推出的下一个控制器
        //2.是否有动画
        //3.推出完成之后回掉
        self.present(vc,animated: true){
            
        }

5. view是懒加载的

6. 属性传值

  • 第二个视图控制器如何获取第一个视图控制器的部分信息
    例如 :第二个界面中的lable显示第一个界面textField中的文本
    这就需要用到属性传值
  • 属性传值就好比是一个渴了的人走到茶水间,向管理员要了一个杯子,然后又让其为自己的杯子倒满水的过程。当然,在编码中情况会更为复杂,因为一个项目工程中,每个类都可能会是管理员,也可能是口渴者,或者二者皆是,而其中又会有很多的杯子(属性)。但如果把这些拿出来一一类比,其实原理都是一样简单。
•    传值者->茶水间管理员,负责管理各种饮品
•    接收者->到茶水间找水喝的人
  •   属性->茶水间的杯子
  •   值->水

7. 实例

实现点击按钮,进入下一个视图,再点击返回上一个视图

import UIKit

class ViewController: UIViewController {
//   override init(nibName nibNameOrNil : String? ,bundle nibBundleOrNil:Bundle?) {
//    //1.加载的xib文件
//    //2.bundle
//    super.init(nibName: nibNameOrNil , bundle: nibBundleOrNil)
//        
//    }
//    required init?(coder aDecoder:NSCoder){
//        fatalError("init(coder:) has not been implemented")
//    }
    //加载view
    override func loadView() {
        super.loadView()
        //替换当前控制器的view
//        let imageV = UIImageView(frame: CGRect(x: 0, y: 0, width: self.view.frame.width, height: self.view.frame.height))
//        self.view = imageV
    }
    //加载相关资源
    override func viewDidLoad() {
        super.viewDidLoad()
        self.view.backgroundColor=UIColor.red
        //视图控制器
        //UIControl子类
        //手势
        let btn = UIButton(type: .system)
        btn.frame=CGRect(x: 100, y: 100, width: 50, height: 40)
        btn.addTarget(self, action: #selector(btnAction(btn:)), for: .touchUpInside)
        btn.setTitle("登录", for: .normal)
        self.view.addSubview(btn)
    }
    func btnAction(btn:UIButton)  {
        //模态推出下一个界面,一般用于注册
        let vc = SecondViewController()
        //1.要推出的下一个控制器
        //2.是否有动画
        //3.推出完成之后回掉
        self.present(vc,animated: true){
            
        }
        
    }
     //视图将要显示在频幕上
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
    }
    //显示在频幕上
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
    }
    //视图将要从频幕上消失
    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
    }
    // 控制器被销毁
    deinit {
        
    }
    //接收到内存警告
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


}

import UIKit

class SecondViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        self.view.backgroundColor=UIColor.white
        let btn = UIButton(type: .system)
        btn.frame=CGRect(x: 100, y: 100, width: 50, height: 40)
        btn.addTarget(self, action: #selector(btnAction(btn:)), for: .touchUpInside)
        btn.setTitle("登录", for: .normal)
        self.view.addSubview(btn)
    }
    func btnAction(btn:UIButton)  {
        //从前页面回收回去
       self.dismiss(animated: true, completion: nil)
     }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    

    
}

相关文章

网友评论

      本文标题:视图控制器

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