簡體   English   中英

稍后在應用中使用prepareForSegue將數據傳遞到ViewController

[英]Using prepareForSegue to pass data to ViewController later in app

我想知道,當使用prepareForSegue傳遞數據時,可以稍后在應用程序中將數據傳遞給View Controller嗎? 例如,在第一個ViewController上,我讓用戶輸入其名稱。 直到最后,所以稍后需要顯示一些名稱。 有沒有一種方法可以傳遞他們的名字而不必立即進入結束視圖?

使用協調員。

解耦ViewController真的很容易:

  • 而不是使用segues給每個ViewController一個委托
  • 創建一個協調器對象(此對象知道您的屏幕流量,而不是您的屏幕)
  • 協調器創建ViewController(可以使用UIStoryboard instantiateViewController(withIdentifier:)因此ViewController A不必知道ViewController B存在
  • 而不是調用performSegue您只需調用您的委托並傳遞數據

好處

  • 使用簡單
  • 輕松重新排列屏幕順序
  • 高度解耦(更輕松的測試)
  • 非常適合A / B測試
  • 擴展很多(您可以有多個協調器,每個流程一個)

樣品

假設您有3個VC,第一個詢問您的姓名,第二個詢問您的年齡,第三個顯示數據。 AgeViewController知道NameViewController存在是沒有意義的,以后您可能想更改它們的順序甚至合並它們。

名稱視圖控制器

protocol NameViewControllerDelegate: class {
    func didInput(name: String)
}

class NameViewController: UIViewController {
    weak var delegate: NameViewControllerDelegate?

    @IBOutlet var nameTextField: UITextField!
    //Unimportant stuff ommited

    @IBAction func submitName(sender: Any) {
        guard let name = nameTextField.text else {
            // Do something, it's up to you what
            return
        }

        delegate?.didInput(name: name)
    }
}

年齡視圖控制器

protocol AgeViewControllerDelegate: class {
    func didInput(age: Int)
}

class AgeViewController: UIViewController {
    weak var delegate: AgeViewControllerDelegate?

    @IBOutlet var ageTextField: UITextField!
    //Unimportant stuff ommited

    @IBAction func submitAge(sender: Any) {
        guard let ageString = ageTextField.text,
              let age = Int(ageString) else {
                // Do something, it's up to you what
            return
        }

        delegate?.didInput(age: age)
    }
}

顯示器視圖控制器

class DisplayerViewController: UIViewController {
    var age: Int?
    var name: String?
}

協調員

class Coordinator {
    var age: Int?
    var name: String?

    var navigationController: UINavigationController

    init(navigationController: UINavigationController) {
        self.navigationController = navigationController
    }

    fileprivate lazy var storyboard: UIStoryboard = {
        return UIStoryboard(name: "MyStoryboard", bundle: nil)
    }()

    //This works if you name your screns after their classes
    fileprivate func viewController<T: UIViewController>(withType type: T.Type) -> T {
        return storyboard.instantiateViewController(withIdentifier: String(describing: type(of: type))) as! T
    }

    func start() -> UIViewController {
        let viewController = self.viewController(withType: NameViewController.self)
        viewController.delegate = self

        navigationController.viewControllers = [viewController]

        return viewController
    }
}

協調器+名稱視圖控制器代表

extension Coordinator: NameViewControllerDelegate {
    func didInput(name: String){
        self.name = name

        let viewController = self.viewController(withType: AgeViewController.self)
        viewController.delegate = self

        navigationController.pushViewController(viewController, animated: true)
    }
}

協調員+年齡視圖控制器代表

extension Coordinator: AgeViewControllerDelegate {
    func didInput(age: Int) {
        self.age = age

        let viewController = self.viewController(withType: DisplayerViewController.self)
        viewController.age = age
        viewController.name = name

        navigationController.pushViewController(viewController, animated: true)
    }
}

並不是的。 您可以逐項查看視圖,但這不是正確的處理方式。

我建議您使用靜態管理器或此類工具將信息全局存儲在您的應用中,以便以后檢索

所有解決方案都很好。 可能您也可以嘗試以下型號

1. DataModel類

1.1 Should be singleton class
1.2 Declare value

步驟1:ViewCOntroller-one

1創建單例類的Sharedinstance
1.1分配值

第三步:ViewController-二

1創建單例類的Sharedinstance
1.1獲得價值

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM