Как установить делегата с помощью раскадровки
Я обсуждал это какое-то время, надеюсь, что вы можете мне помочь.
Я создаю приложение, использующее раскадровки, в основном, у меня есть точка, где я вывожу модальный блок, чтобы добавить новую запись, всплывающее окно отлично работает, проблема в том, что он отклоняет его.
Я следил за инструкциями Apple о том, как правильно закрыть модальные поля с помощью делегатов, и это отлично работает, за исключением того, что мне нужно добавить контроллер навигации в мой модальный блок, потому что процесс добавления требует двух шагов (здесь полноэкранный режим):
![enter image description here]()
Проблема заключается в настройке делегата, так что вот мои два вопроса:
1- В моем классе корневого представления (My Tab) есть делегат класса Add (модальный), все настроено правильно, кроме этого:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:@"showAdd"]) {
[[segue destinationViewController] setDelegate:self];
}
}
Проблема заключается в том, что [segue destinationViewController] возвращает навигационный контроллер, а не класс AddDrinkViewController (см. раскадровку). Как мне обойти это? Если я вообще удаляю навигационный контроллер, код отлично работает с соответствующим делегатом.
2 Есть ли способ установить делегат, перетаскивая розеток в раскадровку?
Спасибо!
Ответы
Ответ 1
Вы правы, destinationViewController
будет UINavigationController
в этом случае. Я написал категорию, чтобы справиться с этой общей ситуацией:
// category .h file
@interface UIStoryboardSegue (NavControllerExtensions)
// Gets destinationViewCotroller. But if that controller
// is a NavigationController, returns the nav controller
// 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.
Ответ 2
Я нашел более короткий способ в моем случае (так же, как ваш):
AddDrinkViewController *controller=[[[segue destinationViewController]viewControllers]objectAtIndex:0];
Ответ 3
В основном вам нужно создать
Экземпляр UINavigationController и назначить ему destinationViewController
и захватите его контроллер 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;
}
}