It's common to see example code that walks the view hierarchy from root to get a pointer to a particular view controller, like this:
UITabBarController *tabBC = (UITabBarController *)self.window.rootViewController;
UINavigationController *navC = [tabBarController viewControllers][0];
MyCustomTableViewController *myVC = [navigationController viewControllers][0];
This is hopelessly fragile, breaking every time the storyboard ordering is revised. What seems to be needed is a UIViewController method like:
/*! recurse through child VCs to find instances of class */
-(NSArray*) childVCsOfClass:(Class)targetClass;
or possibly:
-(NSArray*) childVCsPassingTest: // some useful block
I wrote this scrap to accomplish the simpler case of finding the first instance, but still suspect I'm overlooking something obvious:
/*! Search through hierarchy for correct view controller
TODO: Should be a class extension of ViewController, assuming Apple didn't write it yet
TODO: The double loops are suspect...
*/
UIViewController* FirstChildViewControllerMatchingClass(UIViewController* rootVC, Class targetClass) {
UIViewController *thisController = rootVC;
UIViewController* foundInstance = nil;
if([thisController isKindOfClass:targetClass]) {
return thisController; // found it.
}
// Special case all the collections, etc.
if([thisController respondsToSelector: @selector(viewControllers)]) {
for(id vc in [(id)thisController viewControllers] ) {
foundInstance = FirstChildViewControllerMatchingClass(vc,targetClass);
if(foundInstance) {
return foundInstance; // found it in the tabs
}
}
}
// chug through other possible children
if(thisController.childViewControllers) {
for(UIViewController* kids in thisController.childViewControllers ) {
foundInstance = FirstChildViewControllerMatchingClass(kids,targetClass);
if(foundInstance) {
return foundInstance;
}
}
}
// have I missed other possible children...?
return nil;
}
I'm not particularly asking for reviews of this code, which I've not even tested, I'm trying to figure out if Apple (or someone else) already wrote a sturdy and complete version and I've just not searched the right documents. (OTOH constructive criticism is welcome ;)