可以使用popViewControllerAnimated传递数据吗?

时间:2012-11-22 09:47:52

标签: iphone objective-c ios xcode

我遇到了一个有趣的问题,我有一个主要的ViewController让我用navController调用他的MainVC,我正在从他执行performSegueWithIdentifier到我的第二个ViewController让我们称他为SecVC。所以,当我试图做popViewControllerAnimated我想将一些数据从SecVC传递给MainVc ..我知道我可以用appDelegate Param或单人类来做,但我的问题是:我能用更优雅的解决方案做到吗?就像我使用prepareForSegue并使用本地参数..

谢谢...

5 个答案:

答案 0 :(得分:18)

最好的方法是使用委托。

<强> // SecVCDelegate.h

#import <Foundation/Foundation.h>

@protocol SecVSDelegate <NSObject>

@optional
- (void)secVCDidDismisWithData:(NSObject*)data;
@end

<强> // SecVC.h

#import <UIKit/UIKit.h>
#import "SecVSDelegate.h"

@interface SecVC : UIViewController

/** Returns the delegate */
@property (nonatomic, assign)   id<SecVSDelegate> delegate;

@end

<强> // SecVC.M

...

- (void) dealloc
{
...
delegate = nil
...
}

什么时候popViewControllerAnimated,就在它之后(或之前)你这样做

if(_delegate && [_delegate respondsToSelector:@selector(secVCDidDismisWithData:)])
{
[_delegate secVCDidDismisWithData:myDataObject];
}

在MainVC中,您必须确定您实现了委托功能 的 // MainVC.m

- (void)secVCDidDismisWithData
{
//do whatever you want with the data
}

为了避免任何警告,您必须告诉MainVC类如下所示实现委托:

<强> // MainVC.h

#import "SecVCDelegate.h"
...
@interface MainVC : UIViewController <SecVCDelegate>
...
secVCInstance.delegate = self;
[self.navigationController pushViewController:secVCInstance]; 
...

答案 1 :(得分:15)

虽然我同意最好的选择是使用代表, 但是,如果有人想要寻找不同的东西,他可以使用 NSNotificationCenter 作为替代方案。

在MainVC的 viewDidLoad 中:

- (void)viewDidLoad
{

    [super viewDidLoad];

    [[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(recvData:)
                                             name:@"SecVCPopped"
                                           object:nil];
}

在MainVC.m中添加方法 recvData

- (void) recvData:(NSNotification *) notification
{

    NSDictionary* userInfo = notification.userInfo;
    int messageTotal = [[userInfo objectForKey:@"total"] intValue];
    NSLog (@"Successfully received data from notification! %i", messageTotal);
}

现在在SecVC中,在弹出之前,添加此行

NSMutableDictionary* userInfo = [NSMutableDictionary dictionary];
[userInfo setObject:[NSNumber numberWithInt:messageTotal] forKey:@"total"];

NSNotificationCenter* nc = [NSNotificationCenter defaultCenter];
[nc postNotificationName:@"SecVCPopped" object:self userInfo:userInfo];

答案 2 :(得分:1)

我会通过以下方式之一来做,但我不确定它是否足够优雅......

  1. 在SecVC中,在致电@property MainVC *mainVC;之前添加[self.mainVC setSomeValue:...];使用[self.navigationController popViewControllerAnimated:...];

  2. 使用[self.navigationController viewControllers];找出MainVC *mainVC,并在弹出[mainVC setSomeValue:...];的代码行之前调用ViewController

  3. 这是你想要的吗?

答案 3 :(得分:1)

我只是在视图中设置一个被解雇的协议(例如Swift中):

 protocol ExampleTableViewControllerDismissDelegate {
    func didDismiss(withData: Any)
}

var delegate: SearchableTableViewControllerDismissDelegate?

您可以在解除/弹出您的视图时调用此

self.navigationController?.popViewController(animated: true)
delegate?.didDismiss(withData: Any)

然后在被忽略的视图中(层次结构中的父级),我们可以符合委托,并且在视图被解除后基本上得到数据的回调。

//MARK: ExampleTableViewControllerDismissDelegate

func didDismiss(withData: Any) {
    //do some funky stuff
}

并且不要忘记使用

订阅父视图中的委托
viewController.delegate = self

答案 4 :(得分:0)

还有另一种方法可以在视图之间传递数据,包括 popViewControllerAnimated 以及它带有全局var实例,因此如果您在详细信息视图中修改了Var,之后执行 popViewControllerAnimated ,您可以在viewWillAppear方法中调用新数据。

第一步是在main.h中声明Global var

NSMutableArray * layerList;

现在你必须在详细视图中调用它。

<强> SecondView.m

extern NSString *layerList;

<强> SecondView.h

-(void)back{
    layerList = @"Value to send";
    [self.navigationController popViewControllerAnimated:YES];
}

现在,您可以在检测到弹出操作后使用主视图中的信息。

<强> FirstView.m

extern NSString *layerList;

<强> FirstView.h

-(void)viewWillAppear:(BOOL)animated{
   NSLog(@"This is what I received: %@",layerList);
}