Передать данные из дочернего контроллера обратно в родительский контроллер

Я работаю над приложением для iPad, где имею дело с двумя контроллерами. Мой родительский контроллер (скажем, контроллер A) имеет ячейку, которая при нажатии вызывает/переходит к дочернему контроллеру (скажем, контроллеру B) через pushViewController, как показано ниже:

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

    ControllerB *controllerB = [[ControllerB alloc] initWithStyle:UITableViewStyleGrouped];

    UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithTitle:@"Back" style:UIBarButtonItemStyleBordered
                                                                  target:nil action:nil];
    [self.navigationItem setBackBarButtonItem:backButton];
    [self.navigationController pushViewController:controllerB animated:YES];
} 

Теперь в ControllerB я имею дело с переключателем, который должен поддерживать свое состояние, когда пользователь перемещается назад и вперед от ControllerB к ControllerA, а затем обратно к ControllerB, т.е. пользователь изменяет состояние переключателя на ControllerB (например: YES), возвращается к ControllerA и затем, когда он возвращается к ControllerB, пользователь должен увидеть то же состояние переключателя, в котором он находился, когда возвращался назад. (т.е.: ДА)

Я думаю отправить состояние переключателя из ControllerB в ControllerA, чтобы, когда ControllerB снова инициализировался, можно было отправить состояние переключателя, чтобы установить состояние переключателя.

Несколько вопросов по дизайну:

  • Это хорошая идея, чтобы иметь перекрестное соединение между контроллерами. т. е. ControllerA имеет объект ControllerB, но для отправки обратно состояния переключателя я планировал создать свойство в ControllerA для хранения состояния переключателя и присвоения ему значения состояния переключателя в Controller B. Но для этого мне придется создать объект для ControllerA в ControllerB, который может быть перекрестным соединением.
  • Какими могут быть другие лучшие способы передачи данных с дочернего контроллера на родительский контроллер?

person tech_human    schedule 10.12.2013    source источник
comment
Делегирование — developer.apple.com/library/ ios/документация/общие/ ?   -  person Ivan Genchev    schedule 10.12.2013


Ответы (2)


Нет необходимости привлекать к этому контроллер A, просто не создавайте экземпляр нового контроллера B каждый раз, когда вы нажимаете на него. Создайте свойство для controllerB и проверьте, существует ли контроллер, прежде чем отправлять его.

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (! self.controllerB) {
        self.controllerB = [[ControllerB alloc] initWithStyle:UITableViewStyleGrouped];
    }

    UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithTitle:@"Back" style:UIBarButtonItemStyleBordered
                                                                  target:nil action:nil];
    self.navigationItem setBackBarButtonItem:backButton];
    [self.navigationController pushViewController:self.controllerB animated:YES];
} 

Если вам по какой-либо причине нужно передать данные обратно в контроллер A из контроллера B, вы должны использовать для этого делегата (кстати, контроллер B не является дочерним элементом контроллера A. Они оба являются дочерними элементами навигационного контроллера, что делает их родственными ).

person rdelmar    schedule 10.12.2013
comment
Вы сделали мой день!! Спасибо большое!! Теперь мне не нужны дополнительные делегаты или свойства, чтобы справиться с этим. - person tech_human; 10.12.2013

Я бы сохранил состояние переключателя в глобальном объекте (хорошим вариантом может быть синглтон) или, может быть, CoreData или plist, если вам нужно, чтобы это сохранялось между открытиями приложения. Чтобы сохранить это значение, вам не нужно передавать информацию родительскому контроллеру представления, вы можете делать это каждый раз, когда меняете состояние переключателя.

В любом случае, если вам нужно передать данные в ваш родительский контроллер представления, вы должны использовать делегатов или можете отправить уведомление через NSNotificationCenter, но это не очень обычно, и я рекомендую вместо этого использовать делегатов.

person amb    schedule 10.12.2013
comment
Если я использую делегатов, разве я не буду создавать объект для ControllerA в ControllerB? Просто пытаюсь понять, хороший ли это способ иметь объекты контроллера друг в друге. - person tech_human; 10.12.2013
comment
Насколько я понимаю ваше предложение, использование делегатов или нет не связано с созданием объекта или свойства в одном из ваших контроллеров представления. Например, если вы хотите сохранить состояние переключателя в контроллере A, у вас должно быть что-то в контроллере A для сохранения этого состояния. - person amb; 10.12.2013
comment
Да, я бы создал свойство или делегат для обработки состояния переключателя в контроллере A... возможно, делегат был бы лучшей идеей. - person tech_human; 10.12.2013
comment
Спасибо за ответ!! - person tech_human; 10.12.2013
comment
Имейте в виду, что свойство != делегат. Один похож на ivar (переменная в вашем классе) с геттером/сеттером, а другой — способ передачи сообщений между контроллерами представления. - person amb; 10.12.2013