Reputation: 17695
Overview
I have an iOS project which contains 2 navigation controllers as shown in the pic attached below.
I would like to pass some data when it segues from AAA to CCC but there is a navigation controller between AAA and CCC.
According to Apple's documentation, UINavigationController shouldn't be subclassed, so I can't create a delegate and pass data.
Question:
Upvotes: 7
Views: 3754
Reputation: 3780
For anyone who is unclear on how to implement the accepted answer, here is a code example to more clearly explain how to "have a pointer to the navigation controller." The following code passes an NSString from AAA (AAAViewController) to CCC (CCCViewController) with an identifier named "ToCCC" for the segue.
1) Create a pointer to foo
in CCCViewController.h
.
// CCCViewController.h
#import <UIKit/UIKit.h>
@interface CCCViewController : UITableViewController
@property (strong, nonatomic) NSString *foo;
@end
2) In AAAViewController.m
, create a pointer to CCCViewController (via the navigation controller) and then set foo
.
// AAAViewController.m
#import "AAAViewController.h"
#import "CCCViewController.h" // Note the import statement for CCC.
@implementation AAAViewController
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString: @"ToCCC"])
{
CCCViewController *ccc = [[segue.destinationViewController viewControllers] objectAtIndex: 0];
ccc.foo = @"A string passed from AAA";
}
}
@end
3) Do something with foo
in CCCViewController.m
(e.g. log it to the console).
// CCCViewController.m
#import "CCCViewController.h"
@implementation CCCViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Log foo to the console.
NSLog(@"%@", _foo);
}
@end
Upvotes: 4
Reputation: 1584
A nice solution is to create a category on UIStoryboardSeque
UIStoryboardSegue+TopLevel.h
@interface UIStoryboardSegue (TopLevel)
@property (readonly) id topLevelDestinationViewController;
@end
UIStoryboardSegue+TopLevel.m
@implementation UIStoryboardSegue (TopLevel)
- (id)topLevelDestinationViewController
{
id dest = self.destinationViewController;
if ([dest isKindOfClass:[UINavigationController class]]) {
UINavigationController* nav = dest;
dest = nav.topViewController;
}
return dest;
}
@end
Then to use the category
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
[super prepareForSegue:segue sender:sender];
if ([[segue topLevelDestinationViewController] respondsToSelector:@selector(setSomeProperty:)])
{
[[segue topLevelDestinationViewController] performSelector:@selector(setSomeProperty:) withObject:self.someProperty];
}
}
That way your code can become very generic, and it doesn't matter if the destination view controller for the segue is a navigation controller or not
Upvotes: 0
Reputation: 7703
If you have a pointer to the navigation controller, you can get its viewControllers array. In that array, objectAtIndex:0 will be CCC.
Upvotes: 9