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

Eri*_*ric 2 storyboard swift

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

我试过"prepareForSegue",但它似乎没有触发嵌入式视图控制器.

我试图在测试项目中隔离问题:

在此输入图像描述

主VC代码:

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

    override func viewDidLoad() {
        super.viewDidLoad()
        label1.text = "Hello"
    }
}
Run Code Online (Sandbox Code Playgroud)

嵌入式VC代码:

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

    override func viewDidLoad() {
        super.viewDidLoad()
        //label2.text = how to get value of label1 ?
    }
 }
Run Code Online (Sandbox Code Playgroud)

谢谢你的帮助 :)

Cru*_*ruz 7

首先你不能直接设置EmbeddedVC的lable2.text In prepareForSegue

因为呼叫顺序如下

  1. MainVC prepareForSeque这次是EmbeddedVC的label2是零
  2. viewDidLoad然后加载EmbeddedVC,然后加载label2
  3. viewDidLoad然后调用MainVC 然后加载label1

所以如果你分配MainVC's label1.textEmbeddedVC's label2.textprepareForSeque 两个label1和label2都为零所以没有工作

有两种方法可以解决这个问题

第一个解决方案MainViewController具有EmbeddedVC,当viewDidLoad调用MainVC 时,将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()
    }
}
Run Code Online (Sandbox Code Playgroud)

第二个解决方案,使用协议并在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()
    }
}
Run Code Online (Sandbox Code Playgroud)


小智 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."
    }   
}
Run Code Online (Sandbox Code Playgroud)