Question

I have a UIViewController (let's call it "EditViewController") which has a Container View on it (call it "ContainerView") where I switch in and out various subviews (call the one I'm most concerned with "EditDetailsView").

From the EditDetailsView I need to change the title in the navigation bar of the EditViewController. I can't seem to be able to figure out how to reference it.

From inside EditViewController I can simply make a statement like:

self.title = @"Some new title";

and it changes just fine.

But from the EditDetailsView view that is currently the subview of ContainerView nothing seems to work:

self.title = ... is obviously wrong.

super.title = ... doesn't work and seems wrong anyway.

super.super.title = ... errors out as super is not a property found on UIViewController.

Can someone please tell me how to reference the title? I'm kinda lost.

Thanks!

Was it helpful?

Solution

While digging through the parentViewController chain is possible, it is error prone and unrecommended. It is considered a bad design. Imagine you set up your view controller hierarchy in some manner, but after a few months change it a bit and now there is one level deeper. Or, you would like to use the same view controller in several different scenarios. A much better design would be to pass the new title to the container view controller using delegation. Create a delegate protocol, with a method for setting the title.

- (void)childViewController:(ChildViewController*)cvc didChangeToTitle:(NSString*)title;

OTHER TIPS

I know this is an old thread, but in case someone else needs it: to avoid boilerplate code with delegation, and avoid digging into the parentViewController, I did it the other way around.

I've referenced the child view controller from the parent and got their title. So no matter which child you show, you will always get the right title.

This is in Swift 3.

So, basically, this is your parent:

class EditViewController: UIViewController {
    override func viewDidLoad() {
        if let child = self.childViewControllers.first {
            self.title = child.title
        }
    }
}

And this is your child:

class ContainerView: UIViewController {
    override func viewDidLoad() {
        self.title = "Sbrubbles"
    }
}

Another good way to avoid excess code with delegation is to use RxSwift, if you are familiar to Reactive programming.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top