Because of the way I am not getting my app to pass data as I intend, I am lead to ask the following questions:
prepareForSegue
method in a Navigation Controller ever get called? If so, how?I have the following:
JRMUserViewController
(which extends UIViewController
).JRMNavigationToUserViewController
(which extends UINavigationController
).JRMIssuesTableViewController
(which extends UITableViewController
).IssuesToUserView
".The idea is that when I am on the Issue Table View Controller, I can click on the button and it will take me to the User View Controller, where I will see the current user's avatar, and a label with the current user's full name.
To accomplish this (before I embeded the User View Controller in the Navigation Controller), I passed data from the JRMIssuesTableViewController
to the JRMUserViewController
in the former's prepareForSegue method:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
NSLog(@"\nSEGUE IDENTIFIER:\n%@", [segue identifier]);
if([[segue identifier] isEqualToString:@"IssuesToUserView"]) {
JRMUserViewController *vc = [segue destinationViewController];
vc.currentUser = self.currentUser;
NSURL *url = [[NSURL alloc] initWithString:[vc.currentUser.avatarUrls objectForKey:@"48x48"]];
NSLog(@"\nURL:\n%@", url);
NSData *data = [NSData dataWithContentsOfURL:url];
[vc.view addSubview:vc.avatar];
[vc.avatar setImage:[[UIImage alloc] initWithData:data]];
vc.userLabel.text = vc.currentUser.displayName;
}
}
And it worked. Clicking the button on the first view took me to the second view, where the current user's information was displayed:
After this, out of necessity, I had to embed User View Controller in the Navigation Controller that I mentioned earlier. Now of course, after doing this, I had uncaught exceptions at runtime because, in my overridden prepareForSegue, I was sending messages to the Navigation Controller instead of to the User View Controller. To fix this, I extended UINavigationController
, naming it JRMNavigationToUserViewController
, and linked the Navigation View to it, as I mentioned in the setup.
Then, figuring that a UINavigationController
would call its own prepareForSegue
before going to its embedded View, I overrode the prepareForSegue
method in JRMNavigationToUserViewController
:
- (id)passValuesToDesitinationOfSegue:(UIStoryboardSegue *)segue {
NSLog(@"Calling [JRMNavigationToUserViewController passValuesToDestinationOfSegue]");
JRMUserViewController *destination = [segue destinationViewController];
destination.server = self.server;
destination.currentUser = self.currentUser;
destination.avatar = self.avatar;
[destination.view addSubview:destination.avatar];
destination.userLabel = self.userLabel;
return destination;
}
#pragma mark - Navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
NSLog(@"Calling [JRMNavigationToUserViewController prepareForSegue]");
[self passValuesToDesitinationOfSegue:segue];
}
This time, when I clicked on the button, the User View Controller did not receive the data. It looked like this:
Apparently, the prepareForSegue
method in JRMNavigationToUserViewController
was never called, as it would have logged the message:
Calling [JRMNavigationToUserViewController prepareForSegue]
Calling [JRMNavigationToUserViewController passValuesToDestinationOfSegue]
I could not find these lines printed anywhere in the console.
Here again are my questions:
prepareForSegue
method in a Navigation Controller ever get called? If so, how?You're misusing UINavigationController
here. Take a look at your storyboard: you've got a table controller that somehow presents a navigation controller, which in turn has a user controller as its root controller. I think what you want is to have the navigation controller contain the table controller, and have taps on the table trigger a push segue to the user view controller. So, the nav controller should be on the left with the table controller in the middle and the user controller on the right.
Then, the -prepareForSegue:sender:
method in the table controller would be written such that it looks at the selected cell and sets the corresponding attributes of the user controller (which is the segue's destination).