在 2 个子视图控制器之间来回传递数据

Posted

技术标签:

【中文标题】在 2 个子视图控制器之间来回传递数据【英文标题】:Passing data back and forth between 2 child views controllers 【发布时间】:2012-09-14 01:23:32 【问题描述】:

想看看是否有人可以就如何解决我目前在 iPad 应用程序中遇到的这个问题提供一些建议/指示。这是我在下面描述的图形的链接 http://www.yogile.com/dsruyzk7/41m/share/?vt=QANtu4j

基本上我有一个包含 2 个子视图控制器的 parentViewController。孩子 1 有一个 UITableView 和 Child 2 有一个自定义 UIView。我能够从 didSelectRowAtIndexPath 将 Child 1 上的 UITableview 的信息加载到 Child 2 上的自定义 UIView。数据出来后 显示在孩子 2 我做一些处理。处理完成后,我需要更新 Child 1 上的 UITableView 以便新的/更新的数据 显示在 UITableView 上。我尝试在 Child 1 上创建一个代表,但没有工作,也许我设置了错误。因此,任何帮助建议将不胜感激。

谢谢

.h on Child 2 ViewController

@class Child2ViewController;

@protocol child2Delegate <NSObject>
- (void)refreshTable:(Child2ViewController*)controller passedDict:(NSDictionary *)dict;

@interface Child2ViewController:UIViewController<UITableViewDataSource, UITableViewDelegate> 
    UITableView *myTableView;
    id<child2Delegate> delegate;
    Child1ViewController *child1VC;


@property (nonatomic, weak) id<child2Delegate> delegate;
…
…

@end

.m on Child 2 ViewController

@synthesize delegate;
…
..
..
#after all the processing is done we are ready to refresh the view
#updatedDictForTableView is basically a NSDictionary and has the updated data needed
#for the UITableview on child1VC.

-(void)processData 
    child1VC.delegate = self
    NSLog(@"Dump the updated Data : %@", updatedDictForTableView);
    [delegate refreshTable:self passedDict:updatedDictForTableView;

.h in Child1 ViewController

@interface Child1ViewController : UIViewController <child2Delegate> 
    ….
    ….
    ..

.m in Child1 ViewController

- (void)refreshTable:(Child2ViewController*)controller passedDict:(NSDictionary *)dict 
    NSLog(@"dump dict %@", dict);
    [myTableView reloadData];


【问题讨论】:

你给代表打电话了吗?发布一些代码,以便我们更清楚地看到您在做什么。 抱歉延迟回复。刚刚添加了一些关于我如何设置委托和调用它们的代码。再次感谢您花时间研究这个问题。 【参考方案1】:

您可以在没有委托的情况下执行此操作,使用 NSNotificationcenter 发送通知,其中包含您在 nsdictionary 中的值: exple :

  // in child1 ( in viewDiDLoad function )
 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(FunctionToReloadData:) name:@"ProcessDone" object:nil];

  // remove the listnerin child1 ( in viDidUnload )
[[NSNotificationCenter defaultCenter] removeObserver:self forKeyPath:@"ProcessDone"];

 //in child2 ( in the end of your processData function )
 [[NSNotificationCenter defaultCenter] postNotificationName:@"ProcessDone" object:nil userInfo:updatedDictForTableView ];


 //in child1
 -(void) FunctionToReloadData:(NSNotification *)notification
 
    // get the sended dictionary
    NSDictionary *tmpDic = [notification userInfo];
     .
     .
     [tableView reloadData];

 

【讨论】:

感谢马雷克的帮助。这行得通。与此方案相关的另一个问题是,当加载父视图时,我需要使用 Child 1 tableview 第一行的数据默认 Child 2 详细信息。我遵循了类似的方法……在 viewDidLoad 中的 Child 1 中创建 postNotification(使用不同的名称),在 Child 2 viewDidLoad 中创建观察者。当我运行时,我在调试器中看到调用子 2 的 addObserver 方法,但观察者中的方法从未被调用。有任何想法吗?这是我的代码... '#child 1 viewDidLoad [[NSNotificationCenter defaultCenter]postNotificationName:@"loadInitialDetails" object:nil userInfo:tmpDict]; #child 2 viewDidLoad [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(loadDetails:) name:@"loadInitialDetails" object:nil]; -(void) loadDetails:(NSNotification *)notification debugLog(@"Received Notification...%@", [notification userInfo]); [self anotherMethodToLoadDetailsBasedOnuserInfo]; ' 如果我理解这个场景并且只是为了确定,你有没有在添加观察者之前实例化 child1 和 child2 ? 是的,两个子 VC 都已被父实例化,并且子 1 上的 tableview 与 viewDidLoad 上的数据一起显示。 您可以使用自定义初始化函数将数据传递给 child2:在 child2 中:-(id) initwithDetails:(NSDictionary*) dic if (self = [ super init ] ) myInfoDictionary = [ [nsdictionary alloc]iniwithdictionary:dic] return self; 我在手机上写了这个,所以验证语法错误。【参考方案2】:

您可以通过将父表视图属性添加到子类来做到这一点(这里将其视为详细视图,或 DetailViewController)

@interface DetailViewController : UIViewController 
...
UITableView *parentTableView;
...

@property (nonatomic, retain) UITableView* parentTableView;

然后在子 2 上显示某些内容之前,在子 1 中的某个位置设置该属性,可能就像在 viewWillAppear 中一样:

- (void)viewWillAppear:(BOOL)animated 
    [super viewWillAppear:animated];
    self.detailViewController.parentTableView = self.tableView;

然后,您就可以在子 2 表视图中重新加载子 1 表视图...

【讨论】:

感谢您的回复。我尝试了这里提到的内容..基本上在 Child 2 上我创建了 parentTableView 属性并合成了它。然后在 Child 1 上,我在 viewWillAppear 中添加了 self.myViewController.parentTable = self.tableView。在孩子 2 上,经过一些处理后,我有 [parentTableView reloadData] 并在孩子 1 的 tableview 上设置了一些断点,希望看到表被刷新..不幸的是,我没有看到 tableview 刷新/重新加载数据......任何想法? 当你到达[parentTableView reloadData]的断点时,你是否验证过你有一个有效的指针(不应该是nil)? 刚刚仔细检查了我使用这种方法的应用程序,它运行良好。我会检查正在更新并保存在子 2 中的数据(详细视图)。如果您更新某些内容并保存,请检查调试器是否正在调用您的 reloadData,并在 cellForRowAtIndexPath 方法的子 1 视图控制器中放置一个断点。它被调用了吗? 感谢您抽出宝贵时间查看此问题。是的,我的 [parentTableView reloadData] 根本没有被执行。所以我没有看到在 child1 上调用了 cellForRowAtIndexPath。正如我之前提到的,我确实有一个指向 parentTableView 的有效指针。

以上是关于在 2 个子视图控制器之间来回传递数据的主要内容,如果未能解决你的问题,请参考以下文章

在传递数据时向后滑动以关闭子 VC

Swift 3 - 在视图控制器之间传递数据,然后再传递给另一个 2

使用 Swift 在 UIPageViewController 子视图之间传递数据

如何在情节提要中的 2 个视图控制器之间传递数据?

在两个视图控制器之间传递数据不起作用

在视图控制器 ios 7 之间传递数据