In a simple test app, i have tried to pass an array object named "thisArray" from the MasterViewController
to the a string named "passedData" in the DetailViewController
. I am using Storyboards and the UIViewController
are embedded inside the navigation controller. Using the prepareForSegue
method, i successfully passed the data between the UIViewController
:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:@"pushData"]) {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
DetailViewController *destViewController = segue.destinationViewController;
destViewController.passedData = [thisArray objectAtIndex:indexPath.row];
}
}
Now for some reasons i want to use didSelectRowsAtIndexPath
instead of prepareForSegue
. I have used this:
- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSMutableString *object = thisArray[indexPath.row];
detailViewController.passedData = object;
}
But it didn't work. I have used the following:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
detailViewController = [[DetailViewController alloc] initWithNibName:@"DetailViewController" bundle:nil];
NSMutableString *object = thisArray[indexPath.row];
detailViewController.passedData = object;
[self.navigationController pushViewController:detailViewController animated:YES];
}
But it also didn't work.
QUESTION:
1) How to correctly write didSelectRowsAtIndexPath
to replace prepareForSegue
?
2) If i use didSelectRowsAtIndexPath
, do i need to remove the segue connection between the UIViewController
in the Storyboard?
3) What if there is really no segue connection between the view controllers, how can i still pass the data between them using didSelectRowAtIndexPath
?
Thanks!
UPDATE: Based on the answer and the comments i received, i have wrote the following:
First i have removed the segue connection between the controllers, set the StoryBoard id DetailViewController
, the name of the class is also DetailViewController
.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UIStoryboard* sb = [UIStoryboard storyboardWithName:@"DetailViewController"
bundle:nil];
UIViewController* vc = [sb instantiateViewControllerWithIdentifier:@"DetailViewController"];
NSMutableString *object = thisArray[indexPath.row];
detailViewController.passedData = object;
[self.navigationController pushViewController:detailViewController animated:YES];
}
but its getting crashed with the following error:
*** Terminating app due to uncaught exception
NSInvalidArgumentException
, reason: 'Could not find a storyboard namedDetailViewController
in bundle
Your second attempt is nearly right. The only thing that's not quite correct is the way you instantiate a view controller from a storyboard: you use initWithNibNamed:
, which is what you use with NIBs but not with storyboards. For storyboards, you need this:
UIStoryboard* sb = [UIStoryboard storyboardWithName:@"theStoryboardId"
bundle:nil];
// If this code is inside a method called by a controller that is itself instantiated
// from a storyboard, you can replace the above line with this.storyboard
UIViewController* detailViewController = [sb instantiateViewControllerWithIdentifier:@"DetailViewController"];
See this question for details.
Once you make the replacement, your code should work as expected.
EDIT :: Here is how your method would look:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UIViewController* detailViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"DetailViewController"];
NSMutableString *object = thisArray[indexPath.row];
detailViewController.passedData = object;
[self.navigationController pushViewController:detailViewController animated:YES];
}