问题
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