Как вы указали, выделение контроллера представления для определения его представления не имеет смысла. Будет ли ваше приложение всегда иметь навигационный контроллер в корне? Если это так, вы можете получить это таким образом ...
// in the app delegate
AppDelegate *appDelegate = self;
// or, if not in the app delegate
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
// either way
UINavigationController *navController = (UINavigationController *)[[appDelegate window] rootViewController];
Обратите внимание на потенциально безрассудное приведение корневого vc как UINavigationController
. Это безрассудно, только если какой-то другой вид VC иногда может быть в корне. Если это ситуация в вашем приложении, то вам нужно проверить ...
UIViewController *vc = [[appDelegate window] rootViewController];
if ([vc isKindOfClass:[UINavigationController self]]) {
UINavigationController *navController = (UINavigationController *)vc;
// carry on from here
} else {
// decide what your "deep link" function does when the wrong root vc is present. maybe start over?
}
Наконец, и я думаю, что проблема, с которой вы столкнулись, как мы определяем, присутствует ли ViewControllerC, и как мы представляем его, если нет? Первая часть проста, потому что навигационные контроллеры имеют свойство viewControllers
. Это массив, представляющий «стек», где первый элемент является корнем, а последний элемент находится сверху. Итак ...
NSInteger index = NSNotFound;
for (UIViewController *vc in navController.viewControllers) {
if ([vc isKindOfClass:[UIViewController self]]) {
index = [navController.viewControllers indexOfObject:vc];
}
}
if (index != NSNotFound) {
// it's on the stack
}
Вот способ спросить, находится ли он на вершине стека ...
[navController.viewControllers.lastObject isKindOfClass:[ViewControllerC self]]
Что делать, если его нет в стеке, решать вам. Одна идея состоит в том, чтобы просто подтолкнуть один. Делайте это так, как вы уже делаете это в своем приложении. Что если он находится в стеке, но не сверху? Если вы хотите, чтобы анимация была там, вы бы открыли ее (анимируя последний всплеск). Поскольку это глубокая ссылка, вам, вероятно, плевать на анимацию. Просто обрежьте список контроллеров навигационных контроллеров ...
if (index != NSNotFound) {
// it's on the stack
navController.viewControllers = [navController.viewControllers subarrayWithRange:NSMakeRange(0, index+1)];
}