问题
The question
I'm working on a iOS app and i have 3 consecutive ViewControllers:
TableViewController --> DetailViewController --> ImageViewController
I perform de forward Segue with a button (Just control drag on Storyboard) and to go back I have a custom back button with
[self.navigationController popViewControllerAnimated:YES];
To send data forward I use
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
[segue.destinationViewController someFunction];
}
To send data to the parent ViewController I can use prepareForSegue in the DetailViewController, but it doesn't work in the ImageViewController and there I have to use Notifications.
It's OK if I use prepareForSegue to send data with popViewControllerAnimated?
Should I use Notifications in both cases?
Some code
What I have in the DetailViewController is a button that perform the Segue to the ImageViewController (just control drag on Storyboard) and a Back Button with:
- (IBAction)backAction:(id)sender {
[self.navigationController popViewControllerAnimated:YES];
}
and then the function:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if([segue.identifier isEqualToString:@"forwardSegue"]) {
[segue.destinationViewController someFuntionToImageViewController];
} else {
[segue.destinationViewController someFuntionToParentViewController];
}
}
I noticed that I can't assign a segue.identifier to the popViewController action.
回答1:
Apple recommends the following way to pass data between view controllers that are navigated by segues:
To pass data forward:
You declare a property on the destination vc and set its value in the prepareForSegue method. (So kind of the way you did it)
@interface SomeViewController
@property (strong, nonatomic) VeryImportantData *data;
//...
@end
@implementation SourceVC
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
VeryImportantData *theData = ...;
segue.destinationViewController.data = theData;
}
To pass data back
You declare a delegate protocol. This could look like this:
@protocol SomeViewControllerDelegate
- (void)someViewController:(SomeViewController *) someVC didFinishWithData:(SomeData *) data;
@end
Your destination vc provides a delegate property:
@property (weak, nonatomic) id<SomeViewControllerDelegate> delegate;
The destination vc calls it's delegates method once it's ready to be closed:
@implementation SomeViewController
- (void) close
{
[delegate someViewController:self didFinishWithData:self.data];
}
And your source controller implements the protocol and sets itself as delegate of the destination vc in the prepareForSegue method.
@implementation SourceVC
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
segue.destinationViewController.delegate = self;
}
//...
- (void)someViewController:(SomeViewController *) someVC didFinishWithData:(SomeData *) data
{
self.receivedData = data;
[self.navigationController popViewControllerAnimated:YES];
}
来源:https://stackoverflow.com/questions/13110123/prepareforsegue-and-popviewcontroller-compatibility