【问题标题】:Pass Data using popToRootViewController使用 popToRootViewController 传递数据
【发布时间】:2014-05-28 03:30:56
【问题描述】:

所以我有一个基本的应用程序,这是它的工作原理。我有一个名为 A 的根视图控制器和一个名为 B 的表视图控制器。当用户在 B 中选择一行时,我会弹回到根视图控制器 A。

我要做的是将被选为 NSString 的行的数据传回根视图控制器 A。然后根据字符串使用此字符串“做某事”。

我尝试过使用 NSNotification 方法,但是我无法使用该字符串来做某事。

这是我尝试过的:

//tableViewB.m
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    [[NSNotificationCenter defaultCenter] postNotificationName:@"passData" object:[[_objects objectAtIndex:indexPath.row] objectForKey:@"title"]];
    [self.navigationController popToRootViewControllerAnimated:YES];
}
//rootViewA.m
-(void)dataReceived:(NSNotification *)noti
{
     NSLog(@"dataReceived :%@", noti.object);

}
-(void)viewDidLoad {
  [super viewDidLoad];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(dataReceived:) name:@"passData" object:nil];
}

我想要做的更像是你在推送 viewController 并使用 perpareForSegue 方法时可以做的事情。

提前感谢您的帮助。

【问题讨论】:

  • 除了发布的其他答案之外,您还可以使用 unwind segue 返回而不是 popToRootViewController,这样您就可以像使用 forward segue 一样使用 prepareForSegue。
  • @rdelmar 我将如何在 didSelectRowAtIndexPath 方法中使用它?
  • 您可以像手动调用任何其他 segue 一样执行此操作 - 为您的 segue 提供一个标识符,然后调用 performSegueWithIdentifier:sender:。您也可以直接从单元格连接展开转场,在这种情况下,您根本不应该实现 didSelectRowAtIndexPath。
  • @rdelmar 所以你说有一个从 TableView B 到根 A 的推送序列,然后在 didSelectRowAtIndexPath 方法中调用 performSegueWithIdentifier:sender: ?
  • 不,不是 push segue,是 unwind segue。如果您从控制器 (B) 连接它,那么您将在 didSelectRowAtIndexPath 方法中调用 performSegueWithIdentifier:sender:,但如果您直接从单元格连接 segue,那么您不需要调用任何东西。

标签: ios objective-c uistoryboardsegue rootview poptoviewcontroller


【解决方案1】:

您正在做正确的事情,但使用了错误的参数。通知帖子中的object: 参数是发送对象。还有另一种 post 方法允许调用者附加userInfo:,如下所示:

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

    // notice the prettier, modern notation
    NSString *string = _objects[indexPath.row][@"title"];
    [[NSNotificationCenter defaultCenter] postNotificationName:@"passData"
                                                        object:self
                                                      userInfo:@{"theString" : string }]
    [self.navigationController popToRootViewControllerAnimated:YES];
}

在接收端,只需使用相同的密钥从通知的用户信息中获取数据:

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

     NSLog(@"dataReceived :%@", notification.userInfo[@"theString"]);
}

【讨论】:

  • 好的,是的,但我需要能够使用在 viewWillAppear 方法中传递回 A 的字符串,我可以这样做。对吗?
  • 是的。如果需要字符串来更新视图,您可以在 dataReceived 方法中执行此操作。或者,如果您想将其保存到 dataReceived 中的视图控制器属性中,您可以在之后的任何时间使用它,包括在该视图控制器的视图重新出现之前。
【解决方案2】:

使用 delegate:会比 NSNotification 更好

tableView.h:

@protocol tableViewDelegate
-(void) tableViewSelectRowWithString:(NSString*)str;
@end

@interface tableView:UITableViewController //or something like this

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

tableView.m:

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath     {
[self.delegate tableViewSelectRowWithString:@"your string"];
[self.navigationController popToRootViewControllerAnimated:YES];
}

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

//rootViewA.h

@interface rootViewA : UIViewController<tableViewDelegate>

//rootViewA.m

//When create tableView and push view:
tableView *t = ....;
tableView.delegate = self

-(void) tableViewSelectRowWithString:(NSString*)str{//use string}

【讨论】:

  • 当我将代码添加到我的 tableView.h 中时,我得到了一堆代码错误。我只是将它粘贴到@intface 行下方。有没有具体要去的地方?
【解决方案3】:

试试这个可能会有所帮助

    MyAController *myController = (MyAController *)[self.navigationController.viewControllers objectAtIndex:0];
    myController.myText = @"My String" ;
    [self.navigationController popToViewController:myController animated:YES];

我已经用了很多次了..它工作正常.. 注意:替换你的类名和字符串。 谢谢:)

【讨论】:

  • 这可能适用于 OP,但请注意 viewControllers 数组是一个堆栈。通常,要获得顶部以下的 vc,请使用 navVC.viewControllers[MAX(0,navVC.viewControllers.length-2)]。长度为 1 的为顶部,长度为 0 的为根。
猜你喜欢
  • 2020-10-13
  • 2013-06-21
  • 2017-02-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-14
  • 2016-05-20
相关资源
最近更新 更多