在 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 个子视图控制器之间来回传递数据的主要内容,如果未能解决你的问题,请参考以下文章
Swift 3 - 在视图控制器之间传递数据,然后再传递给另一个 2