Как установить делегата с раскадровкой - PullRequest
19 голосов
/ 07 ноября 2011

Я уже некоторое время спорю с этим, надеюсь, вы мне поможете.

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

Я следовал инструкциям Apple о том, как правильно закрывать модальные окна с помощью делегатов, и это прекрасно работает, за исключением того, что мне нужно добавить контроллер навигации в мое модальное окно, поскольку процесс добавления требует двух шагов (здесь полный экран ):

enter image description here

Проблема заключается в настройке делегата, поэтому вот мои два вопроса:

1- В моем корневом классе просмотра (Моя вкладка) есть делегат класса Add (модальный), все настроено правильно, кроме этого:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if ([[segue identifier] isEqualToString:@"showAdd"]) {
        [[segue destinationViewController] setDelegate:self];

    }
}

Проблема заключается в том, что [segue destinationViewController] возвращает навигационный контроллер, а не класс AddDrinkViewController (см. Раскадровку). Как мне обойти это? Если я вообще удалю контроллер навигации, код будет работать нормально, установив соответствующий делегат.

2- Можно ли установить делегата, перетащив розетки в раскадровку?

Спасибо!

Ответы [ 3 ]

13 голосов
/ 07 ноября 2011

Вы правы, destinationViewController будет UINavigationController в этом случае.Я написал категорию для решения этой распространенной ситуации:

// category .h file
@interface UIStoryboardSegue (NavControllerExtensions)
// Gets destinationViewCotroller. But if that controller 
// is a NavigationController, returns the nav controller's 
// top level view controller instead.
@property (readonly) id topLevelDestinationViewController;
@end

// category .m file
@implementation UIStoryboardSegue (NavControllerExtensions)
- (id)topLevelDestinationViewController
{
  id dest = self.destinationViewController;
  if ([dest isKindOfClass:[UINavigationController class]]) {
    UINavigationController* nav = dest;
    dest = nav.topViewController;
  }
  return dest;
}
@end

Так что теперь вы можете просто сделать это любым из ваших prepareForSegue методов, и вам не нужно беспокоиться о том, существует ли NavigationController:

[[segue topLevelDestinationViewController] setDelegate:self]
// another example:
MyViewController *vc = segue.topLevelDestinationViewController;
vc.delegate = self; // etc.

Чтобы ответить на ваш второй вопрос, я не смог найти способ установить делегата в IB.

9 голосов
/ 13 декабря 2011

Я нашел в моем случае более короткий путь (такой же, как ваш):

AddDrinkViewController *controller=[[[segue destinationViewController]viewControllers]objectAtIndex:0];
4 голосов
/ 05 февраля 2014

В основном вам нужно создать
Экземпляр UINavigationController и назначение ему назначения ViewController
и возьмите его контроллер topView

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if ([[segue identifier] isEqualToString:@"showAdd"]) {

    UINavigationController *navigationController = segue.destinationViewController;
    AddDrinkViewController *addDrinkcontroller = (AddDrinkViewController *)navigationController.topViewController;

    addDrinkcontroller.delegate = self;

   }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...