简体   繁体   中英

Cannot update embedded child VC from non-parent VC

Up to date Xcode/Swift/iOS.

I have a Master VC (called StartVC) that contains a Child VC (called TopBarVC) via and embedded segue. The Child VC contains a button, that, when pressed, modally segues to a 3rd VC (called CategoryPickerOverlayVC) (the view in this VC serves as a dropdown box for picking a category).

    @IBAction func CategoryFilterButtonPressed(_ sender: Any) {

    performSegue(withIdentifier: "toCategoryPickerOverlay", sender: self)

}

When an option is selected from the dropdown box, which itself is composed of three buttons, the title of the selected button should be used to replace the title text of the button in the Child VC.

In the Master VC, I use prepareforsegue to store a reference to the Child VC in a variable - "topBarReference" - at the moment when the embed segue takes place.

 var topBarReference: TopBarVC?


    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {        
    if segue.identifier == "TopBarPane"{
        topBarReference = segue.destination as? TopBarVC
    }
}

Then, in the 3rd VC, when I click on one of the button options in the dropdown box, the button title is sent via a prepareforsegue to update the button in the Child VC (via "topBarReference").

        if segue.identifier == "unwindToStartVC"{

        let vc = segue.destination as! StartVC

        vc.topBarReference?.filterButtonText = ((sender as! UIButton).titleLabel?.text)!

    }

The 3rd VC then unwind segues back to the Master VC. I should add that when the button in the Child VC is changed, a variable (filterButtonText) in Child VC is first set with the title text and then this variable is then used to set the button title text via the viewDidAppear method of Child VC.

When using the debugger, I also note that viewDidAppear in the Master VC does not seem to execute after unwinding (I placed a diagnostic print-to-console in viewDidAppear and nothing prints after the unwind segue). I realise this would explain the button not getting updated but I've got no idea why viewDidAppear does not run.

I have also tried using a delegate protocol and instantiateViewController(withString:) to no avail. All of the methods produce the same result, which is that the button in the Child VC does not get updated. No errors are shown. Everything else happens as expected.

Any ideas as to what I am doing wrong?

Do you mean something like this?

在此处输入图片说明

If so, the solution I used was very simple: the third VC uses prepareForSegue to set a property of the embedded VC, and the embedded VC picks up that property in the unwind method.

In my implementation, the three view controllers are called ViewController, ChildViewController, and ThirdViewController. This is the entire code (everything else is configured in the storyboard):

class ChildViewController: UIViewController {

    @IBOutlet weak var theButton: UIButton!
    var buttonTitle : String?

    @IBAction func unwind(_:UIStoryboardSegue) {
        self.theButton.setTitle(self.buttonTitle, for: .normal)
    }

}
class ThirdViewController: UIViewController {

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        (segue.destination as! ChildViewController).buttonTitle = (sender as! UIButton).currentTitle
    }

}

Ok, so I have found that my original code works fine bar one line in the prepareforsegue of the Child VC. If I change that prepareforsegue from:

        if segue.identifier == "unwindToStartVC"{

        let vc = segue.destination as! StartVC
        vc.topBarReference?.CategoryFilterButton.titleLabel?.text = ((sender as! UIButton).titleLabel?.text)!

    }

to this:

        if segue.identifier == "unwindToStartVC"{

        let vc = segue.destination as! StartVC
        vc.topBarReference?.CategoryFilterButton.setTitle((sender as! UIButton).titleLabel?.text, for: .normal)

    }

it works just fine. The use of the .setTitle method seems to make a difference although I am not sure why.

Thanks to Matt for giving me the idea to change it to that. Matt's method did work when i tried it, although, as I am unwinding to the Master VC and not the Child VC, I had to edit the code accordingly, in terms of where I placed it.

As my little "discovery" equates to the smallest change to the original code, I'll mark this as the answer.

Thanks to all for taking the time to respond!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM