Question

My apologies for the long title, but it really is the shortest accurate and descriptive version I could come up with.

I'm implementing a custom container view controller with a custom segue type, working with iOS 5 and storyboards. I also provide a delegate protocol for contained view controllers, intended to work much like UINavigationControllerDelegate. Currently I'm sending a delegate message from my custom container that informs the segued-from child view controller of a condition relating to my custom segue that it needs to know about to perform a certain action.

This is simple enough with my own UIViewController subclasses, which I can specify to conform to the protocol in the .h file.

However, when the contained view controllers of my custom container are built-in containers themselves (e.g. UINavigationController, UITabBarController), the delegate message I'm sending doesn't necessarily make sense for that contained container, but it would for the active child view controller that that container is currently showing. The built-in containers obviously forward the usual view(Will|Did)(Disa|A)ppear calls to their children, but I don't see a generic way of extending that forwarding to my custom message.

The quick and dirty solution would be to subclass that built-in container and add delegate message forwarding to it. For example, MyTabBarController would conform to the delegate protocol and forward the delegate message to its selectedViewController. An alternative is for my custom container to actively sniff if the view controller it contains is a itself type of container, but this is even dirtier and cannot account for future container types that may one day be nested inside my custom container.

This whole custom containment arrangement is very specific to my current app, so I could just hack it since I know what the requirements are and I don't need to make this generic, but I sure would like to follow good design practice in this area just in case I need to make it significantly more generic in the future, through potential reuse in future apps.

So, any suggestions beyond the two solutions I already described?

Was it helpful?

Solution 2

After giving it some more thought and experimenting for a bit, I came up with a third approach: categories. It's still not as generic as I'd like, but a step up from what I had before and no longer reliant on subclassing built-in container controllers.

For my specific needs, I wanted a tab bar controller to forward the delegate message to its selected view controller. I created a category on UITabBarController called MessageForwarding with an implementation of the correct method signature. The category method just forwarded the identical call to self.selectedViewController, returning the result.

My custom container class then imported this category, and voilà, tab bar controllers now magically do the right thing and forward the delegate message I send in my container.

A similar category would be trivial to implement for split view and navigation controllers and any custom containers one cares to use.

OTHER TIPS

I would use a formal protocol, and when the parent wants to communicate with a child, just ask it if it conforms to the protocol. Similar to a category but you don't have to ask e instance every time you call a category method. Just ask it if it responds to the protocol once and then you can call whatever protocol method you want.

See NSObject's -conformsToProtocol:.

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