转载

Controller 之间使用代理传值

Controller 之间使用代理传值 控制器之间经常需要互相传递值,第一个控制器(简称 MasterVC)在通过 NavigationController Push 第二个控制器(简称 DetailVC)的时候,可以捕获到 DetailVC,所以可以设定后者的变量。而 DetailVC 在给 MasterVC 传递值的时候,比如设定 MasterVC 的 Title,却不能用同样的方式传值(试一下就知道了),而且因为我们要通过 NavigationController 返回原来的界面而不是 push 一个新的界面,所以也不能通过 segue 传值,解决方法我尝试了两种:

  1. 使用 static var
  2. 使用代理传值

使用 static var

class MasterVC: UIViewController {     static var text:String! = ""     override func viewWillAppear(animated: Bool) {         title = MasterVC.text     } }  class DetailVC: UIViewController {     override func viewWillDisappear(animated: Bool) {         MasterVC.text = "xxx"     } } 

这样虽然行得通,但是代码丑陋:类似 viewWillAppear 这样的方法,让人难以读懂,为什么这样的事情要在这个地方做,没有明显的道理;在 MasterVC 内部,仍然需要以 MasterVC.text 这样蹩脚的方式调用。

使用代理传值

说白了我们只是希望 MasterVC 有一个 setControllerTitle(text:String) 这样的方法,然后在 DetailVC 里面适时地调用这个方法就好了。于是解决方案是:将 MasterVC 设为 DetailVC 的代理,DetailVC 以代理作为桥梁,来调用 MasterVC 里面的 setControllerTitle(text:String) 方法,而 MasterVC 只需要遵守一个相应的传值协议,协议里面要求必须实现的方法,就是 setControllerTitle(text:String) 这个方法。

//  PassDataDelegate.swift  import Foundation  protocol PassDataDelegate {     func setControllerTitle(text:String) }   //  MasterVC.swift  import UIKit  class MasterVC: UIViewController, PassDataDelegate {      @IBOutlet weak var textField: UITextField!      override func viewDidLoad() {         super.viewDidLoad()     }       // MARK: - Pass Data     @IBAction func goNextController(sender: AnyObject) {         guard let vc = storyboard?.instantiateViewControllerWithIdentifier("DetailVC")             as? DetailVC else { return }         guard let txt = textField.text else { return }         vc.title = txt // pass data         vc.delegate = self // get data by set delegate         navigationController?.pushViewController(vc, animated: true)     }       // MARK: - PassDataDelegate Method     func setControllerTitle(text:String) {         title = text     }  }   //  DetailVC.swift  import UIKit  class DetailVC: UIViewController {      @IBOutlet weak var textField: UITextField!     var delegate: PassDataDelegate!      override func viewDidLoad() {         super.viewDidLoad()     }       // MARK: - Pass Data     @IBAction func goBackLastController(sender: AnyObject) {         if delegate != nil {             guard let txt = textField.text else { return }             delegate.setControllerTitle(txt)         }         navigationController?.popViewControllerAnimated(true)     }  } 

相比之前的方法,我们获得的额外的好处是:假如我们传递的不只是字符串,而是大量的信息,比如十个不同类型的值,使用代理传值依然只需要实现一个方法,而在之前的解决方案中,我们需要写十行 static var

完整项目

原文  http://kyxu.tech/2016/05/18/Controller-之间使用代理传值/
正文到此结束
Loading...