簡體   English   中英

如何在解除ViewController時將數據傳遞給另一個控制器?

[英]How to pass data to another controller on dismiss ViewController?

我想將我的數據從一個ViewController傳遞給另一個VC關閉VC。 可能嗎?

我嘗試過下一個方法但沒有成功:

點擊按鈕:

self.dismiss(animated: true) { 
        let storyboard = UIStoryboard(name: "Main", bundle: nil)
        let controller = storyboard.instantiateViewController(withIdentifier: "EditViewController") as! EditViewController
        controller.segueArray = [values]
    }

EditViewController再次出現時,我的segueArray就是nil

如何在解除時將我的數據從my ViewController傳遞給EditViewController

將數據傳遞回前一個視圖控制器的最佳方法是通過委托......當從ViewController A轉到B時,將視圖控制器A作為委托傳遞,並在ViewController B的viewWillDisappear方法上,在ViewController A中調用委托方法。協議將有助於定義代理以及之前VC要實現的所需方法。 這是一個簡單的例子:

傳遞數據的協議:

protocol isAbleToReceiveData {
  func pass(data: String)  //data: string is an example parameter
} 

Viewcontroller A:

class viewControllerA: UIViewController, isAbleToReceiveData {

  func pass(data: String) { //conforms to protocol
  // implement your own implementation
   }

  prepare(for: Segue) {
    /** code for passing data **/
    let vc2 = ViewCOntrollerB()  /
    vc2.delegate = self   //sets the delegate in the new viewcontroller 
                          //before displaying
    present(vc2)
  }
}

解除viewcontroller:

class viewControllerB: UIViewController {

  var delegate: isAbleToReceiveData

  viewWillDisappear {
      delegate.pass(data: "someData") //call the func in the previous vc
  }
}

在dismiss completion塊中,您將創建EditViewController的新實例。 我假設另一個EditViewController實例存在於導航堆棧中,您需要找到該實例並將segueArray設置為值。 您可以通過迭代導航堆棧的viewcontrollers來實現:

viewController.navigationController?.viewControllers.forEach({ (vc) in
    if let editVC = vc as? EditViewController {
        editVC.segueArray = ....
    }
})

但我建議使用委托模式,如:

protocol EditViewControllerDelegate: class {
    func setSegueArray(segues: [UIStoryboardSegue])
}

在viewcontroller(稱之為ViewController)中,dismiss塊是,聲明一個委托屬性:

class ViewController: UIViewController {
    weak var delegate: EditViewControllerDelegate?
    ....
}

然后在呈現(我假設從EditViewController)ViewController的實例設置委托像:

...
if let vc = presentingViewController as? ViewController {
    vc.delegate = self
}

並將EditViewController符合委托協議,如:

extension EditViewController: EditViewControllerDelegate {
    func setSegueArray(segues: [UIStoryboardSegue]) {
        // Do the data setting here eg. self.segues = segues
    }
}

要檢測何時在視圖控制器上按下后退按鈕,我只需使用:

override func didMove(toParentViewController parent: UIViewController?) {
    guard parent == nil else { return } // Back button pressed

    ... // Pass on the info as shown in you example
} // didMoveToParentViewController

通用解決方案:(🔸Swift5.1)

/**
 * Returns a ViewController of a class Kind
 * ## Examples:
 * UIView.vc(vcKind: CustomViewController.self) // ref to an instance of CustomViewController
 */
public static func vc<T: UIViewController>(vcKind: T.Type? = nil) -> T? {
   guard let appDelegate = UIApplication.shared.delegate, let window = appDelegate.window else { return nil }
   if let vc = window?.rootViewController as? T {
      return vc
   } else if let vc = window?.rootViewController?.presentedViewController as? T {
      return vc
   } else if let vc = window?.rootViewController?.children {
      return vc.lazy.compactMap { $0 as? T }.first
   }
   return nil
}

暫無
暫無

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

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