Передача данных с помощью popToRootViewController

Итак, у меня есть базовое приложение, вот как оно работает. У меня есть контроллер корневого представления с именем 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.

Заранее спасибо за помощь.


person Community    schedule 28.05.2014    source источник
comment
В дополнение к другим опубликованным ответам для возврата вы можете использовать размотку, а не popToRootViewController, что позволит вам использовать prepareForSegue так же, как и для прямого перехода.   -  person rdelmar    schedule 28.05.2014
comment
@rdelmar, как мне использовать это в методе didSelectRowAtIndexPath?   -  person    schedule 28.05.2014
comment
Вы делаете это так же, как любой другой сегмент, который вы собираетесь вызывать вручную - вы даете своему сегменту идентификатор и вызываете performSegueWithIdentifier: sender :. Вы также можете подключить последовательность размотки непосредственно из ячейки, и в этом случае вам вообще не следует реализовывать didSelectRowAtIndexPath.   -  person rdelmar    schedule 28.05.2014
comment
@rdelmar, значит, вы говорите, что у вас есть переход от TableView B к корню A, а затем вызовите performSegueWithIdentifier: sender: в методе didSelectRowAtIndexPath?   -  person    schedule 28.05.2014
comment
Нет, не толчок, а расслабляющий. Если вы подключаете его с контроллера (B), вы должны вызвать performSegueWithIdentifier: sender: в методе didSelectRowAtIndexPath, но если вы подключаете переход напрямую из ячейки, вам не нужно ничего вызывать.   -  person rdelmar    schedule 28.05.2014
comment
@rdelmar, когда я нажимаю и перетаскиваю контрольную кнопку, я не вижу возможности размотки?   -  person    schedule 28.05.2014
comment
Это не то, как вы создаете расслабляющий переход. Взгляните на ответ здесь: stackoverflow.com/questions/12561735/   -  person rdelmar    schedule 28.05.2014


Ответы (3)


Попробуй, это может помочь полная

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

Я много раз этим пользовался .. Он работает нормально .. Примечание: замените в нем имя вашего класса и строку. Спасибо :)

person Jogendra.Com    schedule 28.05.2014
comment
Это может сработать для OP, но обратите внимание, что массив viewControllers является стеком. В общем, чтобы получить vc ниже вершины, используйте navVC.viewControllers [MAX (0, navVC.viewControllers.length-2)]. Один на длине-1 - это верх, нулевой - корень. - person danh; 29.05.2014

Вы поступаете правильно, но с неправильными параметрами. Параметр object: в сообщении уведомления - это объект отправки. Есть еще один метод публикации, который позволяет вызывающему прикрепить 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"]);
}
person danh    schedule 28.05.2014
comment
хорошо, да, это работает, но мне нужно иметь возможность использовать строку, которую я передаю обратно A в методе viewWillAppear, что я могу сделать с этим. Правильный? - person ; 28.05.2014
comment
да. Если строка необходима для обновления представления, вы можете сделать это прямо здесь, в методе dataReceived. Или, если вы хотите сохранить его в свойстве контроллера представления в dataReceived, вы можете использовать его в любое время после этого, в том числе непосредственно перед тем, как снова появится представление этого контроллера представления. - person danh; 28.05.2014

Используйте делегат: это было бы лучше, чем 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}
person nmh    schedule 28.05.2014
comment
Когда я добавляю код в свой tableView.h, я получаю кучу ошибок в коде. Я просто вставил его под строкой @intface. Есть какое-то конкретное место, куда он должен пойти? - person ; 28.05.2014