How to set the delegate with a storyboard
Solution 1
You're right, the destinationViewController
will be a UINavigationController
in this case. I wrote a category to handle this common situation:
// category .h file
@interface UIStoryboardSegue (NavControllerExtensions)
// Gets destinationViewCotroller. But if that controller
// is a NavigationController, returns the nav controller's
// top level view controller instead.
@property (readonly) id topLevelDestinationViewController;
@end
// category .m file
@implementation UIStoryboardSegue (NavControllerExtensions)
- (id)topLevelDestinationViewController
{
id dest = self.destinationViewController;
if ([dest isKindOfClass:[UINavigationController class]]) {
UINavigationController* nav = dest;
dest = nav.topViewController;
}
return dest;
}
@end
So now you can just do this in any of your prepareForSegue
methods, and not need to worry about whether there even exists a NavigationController
:
[[segue topLevelDestinationViewController] setDelegate:self]
// another example:
MyViewController *vc = segue.topLevelDestinationViewController;
vc.delegate = self; // etc.
To answer your second question, I couldn't find a way to set the delegate within IB.
Solution 2
I found a shorter way in my case (same as yours):
AddDrinkViewController *controller=[[[segue destinationViewController]viewControllers]objectAtIndex:0];
Solution 3
Basically you need to create an
Instance of UINavigationController and assign destinationViewController to it
and grab its topView controller
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:@"showAdd"]) {
UINavigationController *navigationController = segue.destinationViewController;
AddDrinkViewController *addDrinkcontroller = (AddDrinkViewController *)navigationController.topViewController;
addDrinkcontroller.delegate = self;
}
}
![Admin](/assets/logo_square_200-5d0d61d6853298bd2a4fe063103715b4daf2819fc21225efa21dfb93e61952ea.png)
Admin
Updated on June 06, 2022Comments
-
Admin about 2 years
I've been debating with this for a while now, hope you can help me.
I've been creating an app using storyboards mostly, I have a point where I popup a modal box to add a new record, popup works fine, the problem is dismissing it.
I've followed Apple's instructions on how to properly close modal boxes using delegates, and that works fine, except I need to add a navigation controller to my modal box, because the add process requires two steps (here fullscreen):
The problem lies in setting the delegate, so here are my two questions:
1- In my root view class (My Tab) is a delegate of the Add class (the modal), everything is set up right except this:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { if ([[segue identifier] isEqualToString:@"showAdd"]) { [[segue destinationViewController] setDelegate:self]; } }
The problem lies in that [segue destinationViewController] is returning the navigationcontroller and not the AddDrinkViewController class (see the storyboard). How do I get around this? If I remove the navigation controller altogether, the code works fine setting the appropriate delegate.
2- Is there any way to set the delegate by dragging the outlets in the storyboard?
Thanks!
-
iDroid over 12 yearsNice! Solved my problem like a charm!
-
Matthew Frederick almost 12 yearsPerfect, solved my problem as well. Couldn't understand why I could reference the properties of other viewControllers that use the same nav controller but not those that use another. Phew!