Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to send values to a parent view controller in Swift

Tags:

ios

swift

I am working on a settings view controller screen for my iOS app written in swift. I am using a navigation controller to run the main settings table view which shows the cell titled, "Input Method." The current method is listed on the right of the cell. They can click the cell to go to the next view controller where they can select the input method that they'd like.

From here, there are two sections. The first is the input method to choose (touchscreen or joystick). The second section is joystick specific on whether or not the person is a lefty or righty. I don't want to have the vc unwind when they choose one box because they may choose one in another section too.

My question: How can I update the text field in the parent controller from the child controller.

Problems I'm having for optional solutions:

let parentVC: UIViewController = (self.navigationController?.parentViewController)!
parentVC.inputMethod.text? = cellSelected // This doesn't work because it cannot find the label inputMethod.

viewDidLoad() will cause a lag and the user sees the old method before it changes.

I cannot find out how to run a segue when someone clicks the back button at the upper left hand side in the navigation controller, since the navigation controller controls the segue.

like image 450
Alec O'Connor Avatar asked Feb 16 '16 17:02

Alec O'Connor


People also ask

What is child view controller in Swift?

Child view controllers are especially useful for UI functionality that we wish to reuse across a project. For example, we might want to display a loading view as we're loading the content for each screen — and that can easily be implemented using a child view controller, that can then simply be added when needed.


2 Answers

It is not a good idea to cast the parent view controller, even when you are sure which class represents. I'll do it with a protocol:

In the child controller add a protocol like:

protocol ChildNameDelegate {
    func dataChanged(str: String)
}

class ChildClass {

    weak var delegate: ChildNameDelegate?

    func whereTheChangesAreMade(data: String) {
        delegate?.dataChanged(data)
    }
}

And in the parent:

class ParentClass: ChildNameDelegate {

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        guard let segueId = segue.identifier else { return }

        switch segueId {
        case "childSegue":
            let destVC = segue.destinationViewController as! ChildClass
            destVC.delegate = self
            break
        default:
            break
        }
    }

    // Child Delegate
    func dataChanged(str: String) {
        // Do whatever you need with the data
    }
}
like image 170
javiazo Avatar answered Sep 21 '22 14:09

javiazo


You need to cast the parentViewController to whatever custom class it has. For example, if the parent has the class ExampleParentController, you would write:

let parentVC = (self.navigationController?.parentViewController)! as! ExampleParentController
parentVC.inputMethod.text? = cellSelected
like image 38
thislooksfun Avatar answered Sep 17 '22 14:09

thislooksfun