xcode prepareForSegue 和 popViewController 的兼容性
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13110123/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
prepareForSegue and popViewController compatibility
提问by Octan
The question
问题
I'm working on a iOSapp and i have 3 consecutive ViewControllers:
我正在开发一个iOS应用程序,我有 3 个连续的ViewControllers:
TableViewController--> DetailViewController--> ImageViewController
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
我用一个按钮执行 de forward Segue(只需控制拖动Storyboard)然后返回我有一个自定义后退按钮
[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 ViewControllerI can use prepareForSeguein the DetailViewController, but it doesn't work in the ImageViewControllerand there I have to use Notifications.
为了将数据发送到父ViewController,我可以使用prepareForSegue的DetailViewController,但它不工作ImageViewController,有我一定要使用Notifications。
It's OK if I use prepareForSegueto send data with popViewControllerAnimated?
如果我prepareForSegue用来发送数据可以popViewControllerAnimated吗?
Should I use Notifications in both cases?
在这两种情况下我都应该使用通知吗?
Some code
一些代码
What I have in the DetailViewControlleris a button that perform the Segue to the ImageViewController (just control drag on Storyboard) and a Back Button with:
我在里面DetailViewController有一个按钮,它对 ImageViewController 执行 Segue(只需控制拖动Storyboard)和一个后退按钮:
- (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 popViewControlleraction.
我注意到我无法为popViewController操作分配 segue.identifier 。
回答by Tobi
Apple recommends the following way to pass data between view controllers that are navigated by segues:
Apple 建议使用以下方式在由 segue 导航的视图控制器之间传递数据:
To pass data forward:
向前传递数据:
You declare a property on the destination vc and set its value in the prepareForSeguemethod. (So kind of the way you did it)
您在目标 vc 上声明一个属性并在prepareForSegue方法中设置其值。(所以你这样做的方式)
@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:
您的目标 vc 提供了一个委托属性:
@property (weak, nonatomic) id<SomeViewControllerDelegate> delegate;
The destination vc calls it's delegates method once it's ready to be closed:
一旦准备好关闭,目标 vc 就会调用它的委托方法:
@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 prepareForSeguemethod.
并且您的源控制器实现了协议并将自身设置为prepareForSegue方法中目标 vc 的委托。
@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];
}

