Swift嵌入式视图控制器和父级

时间:2017-01-27 08:51:16

标签: swift storyboard

我有一个嵌入在另一个VC中的视图控制器。 我想从嵌入式VC中的主VC获取变量的值。 我该怎么办?

我试过“prepareForSegue”,但似乎没有触发嵌入式视图控制器。

我试图在测试项目中找出问题:

enter image description here

主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()
        //label2.text = how to get value of label1 ?
    }
 }

感谢您的帮助:)

3 个答案:

答案 0 :(得分:7)

解决这个问题的一种方法是在父视图的viewDidLoad中获取子视图控制器实例。似乎父视图的viewDidLoad:在子视图的viewDidLoad:之后被调用,这意味着标签已经在子视图中创建。

override func viewDidLoad() {
    super.viewDidLoad()

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

答案 1 :(得分:6)

首先,您无法在prepareForSegue

中直接设置EmbeddedVC' lable2.text

因为下面的呼叫序列

  1. MainVC' prepareForSeque这次EmbeddedVC的label2为零
  2. EmbeddedVC' s viewDidLoad已调用然后已加载标签2
  3. MainVC' s viewDidLoad调用然后标签1加载
  4. 因此,如果您将MainVC's label1.text分配给EmbeddedVC's label2.text prepareForSeque 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()
        }
    }
    

答案 2 :(得分:2)

您应该尝试使用这样的prepareForSegue:

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

        destinationViewController.label2.text = mytext
    }

您在故事板中指定的segue标识符