iOS Objective-C: Как определить, что контроллер представления представляет через UINavigationController? - PullRequest
0 голосов
/ 16 мая 2019

В моей реализации есть несколько viewController, например:

ViewControllerA
ViewControllerB
ViewControllerC
ViewControllerD

Но для глубоких ссылок мне нужно загрузить их в ViewControllerC, но я не знаю, загружен ли этот viewcontroller (инициализирован) илиесли присутствует.

Я пробовал это из appDeelegate:

ViewControllerC *rootViewController = [[ViewControllerC alloc] init];
self.navigationController = [[UINavigationController alloc] initWithRootViewController:rootViewController];

Но, похоже, создается новый экземпляр viewController.

Мой вопрос к вам, ребята, как я могу получить экземпляр ViewControllerC, загрузить его в приложение или как определить, не загружен ли пока ViewControllerC?

Буду очень признателен за вашу помощьили обойти.

Ответы [ 2 ]

0 голосов
/ 17 мая 2019

Как вы указали, выделение контроллера представления для определения его представления не имеет смысла. Будет ли ваше приложение всегда иметь навигационный контроллер в корне? Если это так, вы можете получить это таким образом ...

// 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)];
}
0 голосов
/ 16 мая 2019

Для проверки, является ли корневой контроллер представления ViewControllerC

Swift:

if type(of: UIApplication.shared.keyWindow?.rootViewController) == ViewControllerC.self{
    debugPrint("RootViewController is a ViewControllerC")
}

Objective-C:

if ([[[[UIApplication sharedApplication] keyWindow] rootViewController] class] == [ViewControllerC class]){
        NSLog(@"RootViewController is a ViewControllerC");
    }

Для проверки, если ViewControllerC представлен на корневом контроллере представления

Swift:

if let rootViewController = UIApplication.shared.keyWindow?.rootViewController{
    if type(of: rootViewController.presentedViewController) == ViewControllerC.self{
        debugPrint("ViewControllerC is presented on rootViewController")
    }
}

Objective-C:

UIViewController *viewController = [[[UIApplication sharedApplication] keyWindow] rootViewController];
    if (viewController != nil){
        if ([viewController.presentedViewController class] == [ViewControllerC class]){
            NSLog(@"ViewControllerC is presented on rootViewController");
        }
    }

Установить контроллер корневого представления как ViewControllerC

Swift:

if UIApplication.shared.keyWindow != nil{
    let viewController:ViewControllerC = ViewControllerC()
    //You can get above instance from Storyboard if you wanna
    UIApplication.shared.keyWindow!.rootViewController = viewController
}

Objective-C:

UIWindow *window = [[UIApplication sharedApplication] keyWindow];
if (window != nil){
    ViewControllerC *viewController = [[ViewControllerC alloc] init];
    //You can get above instance from Storyboard if you wanna
    window.rootViewController = viewController;
}

Для pushпросмотр контроллера на навигационном контроллере из root, если он существует

Swift:

    if UIApplication.shared.keyWindow != nil{
        if let navigationController = UIApplication.shared.keyWindow!.rootViewController as? UINavigationController{
        let viewController:ViewControllerC = ViewControllerC()
        //You can get above instance from Storyboard if you wanna
        navigationController.pushViewController(viewController, animated: true)
        }
    }

Objective-C:

UIWindow *window = [[UIApplication sharedApplication] keyWindow];
    if (window != nil){
        UINavigationController *navigationController = (UINavigationController*)window.rootViewController;
        if (navigationController != nil){
            ViewControllerC *viewController = [[ViewControllerC alloc] init];
            [navigationController pushViewController:viewController animated:true];
        }
    }

Теперь выможет сделать много вещей, например получить экземпляр ViewControllerC из контроллера навигации, если существует

Objective-C:

UIWindow *window = [[UIApplication sharedApplication] keyWindow];
    if (window != nil){
        UINavigationController *navigationController = (UINavigationController*)window.rootViewController;
        if (navigationController != nil){
            UIViewController *viewController = [navigationController topViewController];
            if ([viewController class] == [ViewControllerC class]){
                NSLog(@"Do what you want with viewControllerC instance");
            }
        }
    }
...