我有一个父母UIViewController,它有两个不同的视图容器- 每个容器都嵌入其中UIViewController。它看起来像 这样:
我想在用户按下 存储在左侧容器上的按钮时更改右侧容器上的标签。
到目前为止,我已经能够在将按钮放在父视图 控制器中的同时做到这一点,然后我只使用了一种协议:
在我的父组件中,我有:
class ParentController: UIViewController { var delegateEmbedded:HandleEmbedded? override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { if (segue.identifier == "segueToFirstEmbeddedController"){ if let embeddedView = segue.destinationViewController as? EmbeddedContainer { self.delegateEmbedded = embeddedView } }
在我的容器嵌入式UIViewController中,我有:
protocol HandleEmbedded: class { func setName(label: String) }
嵌入式容器类:UITableViewController,HandleYourChat {
func setName(label: String){ print("setting label to \(label)") } }
当我将按钮放在父控制器中并且 想要更改容器内的标签时,上述情况起作用。但是会发生什么, 当按钮也被嵌入但 与标签位于不同的容器中时,如何传递数据?我是否必须通过父控制器传递数据? 这样做的最佳方法是什么?
要将数据从一个嵌入式ViewController传递到另一个嵌入式ViewController,请让父级处理传输。在这里,我提供了一个完整的示例,其中包含三个ViewController和一个StringTaker协议。主要ViewController和LabelViewController实现此协议。mainViewController从中获取一个字符串ButtonViewController,并将其传递给嵌入式LabelViewController。
ViewController
LabelViewController
mainViewController
ButtonViewController
ViewController.swift
import UIKit protocol StringTaker: class { func takeString(string: String) } class ViewController: UIViewController, StringTaker { weak var stringTaker: StringTaker? override func viewDidLoad() { super.viewDidLoad() } override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { if segue.identifier == "EmbedButtonViewController" { let dvc = segue.destinationViewController as! ButtonViewController dvc.delegate = self } else if segue.identifier == "EmbedLabelViewController" { let dvc = segue.destinationViewController as! LabelViewController stringTaker = dvc } } // Receive the string from the ButtonViewController func takeString(string: String) { // Pass it to the LabelViewController stringTaker?.takeString(string) } }
ButtonViewController.swift
import UIKit class ButtonViewController: UIViewController { weak var delegate: StringTaker? override func viewDidLoad() { super.viewDidLoad() } @IBAction func generateString(sender: UIButton) { let cities = ["Boston", "Paris", "Sydney", "Mumbai", "Lima"] // Pick a random city let city = cities[Int(arc4random_uniform(UInt32(cities.count)))] // Pass the string to the delegate delegate?.takeString(city) } }
LabelViewController.swift
import UIKit class LabelViewController: UIViewController, StringTaker { @IBOutlet weak var myLabel: UILabel! override func viewDidLoad() { super.viewDidLoad() } func takeString(string: String) { myLabel.text = string } }
注意事项:
viewController
delegate
prepareForSegue