I am trying to pass data from one UITableViewController
to another. This is my code in the initial view controller:
- (void)tableView:(UITableVi
You need to overwrite prepareForSegue:sender:
method. The quick fix would be
- (void)showList:(Subject *)subject animated:(BOOL)animated
{
[self performSegueWithIdentifier:@"showDetail" sender:subject];
}
...
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:@"showDetail"]) {
ListsViewController *controller = ([segue.destinationViewController isKindOfClass:[ListsViewController class]]) ? segue.destinationViewController : nil;
controller.subject = ([sender isKindOfClass:[Subject class]]) ? subject : nil;
}
}
The reason why your code did not work is that in your showList:animated:
method you created a ListsViewController
instance and assigned it a subject
, but this view controller was never presented. Instead performSegueWithIdentifier:sender
creates another instance of your ListsViewController
class which knows nothing about your subject
. That's why you need to wait for UIStoryboardSegue to instantiate a destination view controller from the storyboard and then configure it the way you want, which you can do in prepareForSegue:sender:
method.
Also it might be not the best idea to use subject
as a sender in performSegueWithIdentifier:sender
method, because it's just not the sender :). What I would do is create a property subject in your view controller class and use it prepareForSegue:sender:
@interface MyViewController ()
@property (strong, nonatomic) Subject *subject;
@end
@implementation MyViewController
- (void)showList:(Subject *)subject animated:(BOOL)animated
{
self.subject = subject;
[self performSegueWithIdentifier:@"showDetail" sender:self];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:@"showDetail"]) {
ListsViewController *controller = ([segue.destinationViewController isKindOfClass:[ListsViewController class]]) ? segue.destinationViewController : nil;
controller.subject = self.subject;
}
}
...
@end
Implement prepareForSegue and pass date in this methos
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if([seque.identifier isEqualToString:@"showDetail"])
{
ListsViewController *lists = seque.destinationViewController;
lists.subject = subject;
}
}
You need to understand that performSegueWithIdentifier:sender:
creates a new instance of view controller. So the ListsViewController
that you have created is not the being displayed on the screen.
You need to override `prepareForSegue:sender:
- (void)showList:(Subject *)subject animated:(BOOL)animated
{
[self performSegueWithIdentifier:@"showDetail" sender:self];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:@"showDetail"]) {
ListsViewController *controller = (ListsViewController *)segue.destinationViewController;
controller.subject = self.subject;
}
That's good, but now you need to add this:
First instead of:
[self performSegueWithIdentifier:@"showDetail" sender:self];
You need to send the object:
[self performSegueWithIdentifier:@"showDetail" sender:subject];
Add a property in your ListsViewController.h:
@property (nonatomic, strong) Subject * subjectSegue;
And now in your first view controller:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:@"showDetail"]) {
ListsViewController * lists = (ListsViewController *)[segue destinationViewController];
lists.subjectSegue = sender;
}