簡體   English   中英

如何在 Swift 中將數據從父視圖控制器傳遞到嵌入式視圖控制器?

[英]How can I pass data from a parent view controller to an embedded view controller in Swift?

我有一個嵌入在另一個 VC 中的視圖控制器。 我想從嵌入的主 VC 中獲取變量的值。 具體來說,我想根據 label1 的值更改 label2 的文本。

我嘗試使用“prepareForSegue”,但它似乎不是為嵌入式視圖控制器觸發的。 我試圖在測試項目中隔離問題:

在此處輸入圖片說明

主VC代碼:

class MyViewController: UIViewController {
    @IBOutlet weak var label1: UILabel!

    override func viewDidLoad() {
        super.viewDidLoad()
        label1.text = "Hello"
    }
}

嵌入式VC代碼:

class EmbeddedVC: UIViewController {
    @IBOutlet weak var label2: UILabel!

    override func viewDidLoad() {
        super.viewDidLoad()
    }
 }

謝謝你的幫助 :)

首先不能直接設置EmbeddedVC的label2.text在prepareForSegue

因為調用順序如下

  1. MainVC的prepareForSeque這次EmbeddedVC的label2是nil
  2. EmbeddedVC 的viewDidLoad調用然后 label2 加載
  3. 調用 MainVC 的viewDidLoad然后加載 label1

因此,如果您在prepareForSeque MainVC's label1.text分配給EmbeddedVC's label2.text ,則 label1 和 label2 均為零,因此不起作用

有兩種方法可以解決這個問題

第一個解決方案 MainViewController 有 EmbeddedVC,當 MainVC 的viewDidLoad調用時,將 label1.text 分配給 EmbeddedVC.label2.text

class MyViewController: UIViewController {
    @IBOutlet weak var label1: UILabel!
    var embeddedVC: EmbeddedViewController? = nil

    override func viewDidLoad() {
        super.viewDidLoad()
        label1.text = "Hello"
        embeddedVC?.label2.text = label1.text
    }

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if let embeddedVC = segue.destination as? EmbeddedViewController {
            self.embeddedVC = embeddedVC
        }
    }
}

class EmbeddedViewController: UIViewController {
    @IBOutlet weak var label2: UILabel!

    override func viewDidLoad() {
        super.viewDidLoad()
    }
}

第二種解決方案,在viewWillAppear或viewDidAppear(后來調用viewDidLoad)時使用協議獲取MainVC的標簽文本

protocol EmbeddedVCDelegate: class {
    func labelText() -> String?
}

class MyViewController: UIViewController, EmbeddedVCDelegate {
    @IBOutlet weak var label1: UILabel!

    // MARK: EmbeddedVCDelegate
    func labelText() -> String? {
        return label1.text
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        label1.text = "Hello"
    }

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if let embeddedVC = segue.destination as? EmbeddedViewController {
            embeddedVC.delegate = self
        }
    }
}

class EmbeddedViewController: UIViewController {
    @IBOutlet weak var label2: UILabel!
    weak var delegate: EmbeddedVCDelegate? = nil
    override func viewDidLoad() {
        super.viewDidLoad()
    }

    override viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        label2.text = delegate?.labelText()
    }
}

實現這一點的一種方法是在父視圖的 viewDidLoad 中獲取子視圖控制器實例。 看起來父的 viewDidLoad: 在孩子的 viewDidLoad: 之后被調用,這意味着標簽已經在孩子的視圖中創建。

override func viewDidLoad() {
    super.viewDidLoad()

    if let childVC = self.childViewControllers.first as? ChildVC {
        childVC.someLabel.text = "I'm here. Aye-aye."
    }   
}

您應該嘗試像這樣使用 prepareForSegue:

if segue.identifier == "identifier" {
        guard let destinationViewController = segue.destination as? VC2 else { return }

        destinationViewController.label2.text = mytext
    }

您在故事板中分配的 segue 標識符的位置

暫無
暫無

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

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