Как «выдвинуть» контроллер навигации и все его контроллеры представления - PullRequest
0 голосов
/ 06 февраля 2019

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

Это приложение имеет несколько раскадровок и несколько контроллеров UINavigationController.В одном месте приложения серия контроллеров представления представлена ​​модально с использованием отдельной раскадровки и отдельного контроллера навигации.Когда модальный процесс завершен, навигационная иерархия выглядит примерно так:

NavController1 -> VC1 [Sesent Modally 'segue] -> NavController2 -> VC2 -> VC3 -> VC4

Когда пользователь завершает модальное действие в VC4, dismiss ()вызывается программно на VC4, и пользователь может затем вернуться к VC1 с помощью кнопки «назад».

Однако нам действительно нужно «вытолкнуть» весь модально представленный набор контроллеров представления (и ихконтроллер Nav), когда пользователь заканчивает модальное действие.Проблема в том, что из VC3 или VC4 я не могу вызвать popToRootViewController ().Я также не могу пройтись по стеку VC, чтобы найти VC1, поскольку текущий контроллер Nav не управляет им.

На ум приходит пара решений:

1) использовать диспетчер уведомленийи пусть VC1 прислушается к сообщению, чтобы вернуть все обратно себе

2) передать ссылку на VC1 в качестве делегата по всей цепочке, чтобы VC3 или 4 могли получить от него все

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

Я бы приветствовал любые мысли или альтернативные решения.

Ответы [ 2 ]

0 голосов
/ 06 февраля 2019

При получении сообщения вы можете исключить viewControllers из вашего контроллера навигации, это решит вашу проблему

extension UINavigationController { 
     public func removeViewController(classes : [String]) {
           var vcs = [UIViewControllers]()
           for viewController in self.viewControllers {
               let name = viewController.className
               if !classes.contains(name) {
                    vcs.append(viewController)
                }
           }
           if classes.count < vcs.count {
               self.viewControllers = vcs
           }
    }
}

теперь вы думаете, что у вас есть 4 viewControllers, A, B, C, D, которые вы хотите удалить Bи C и вернуться к A

в D's View Controller

override func viewDidLoad() {
   super.viewDidLoad()
   //your works
   let viewControllersToRemove = [String(describing: type(of:B)), String(describing: type(of:C))]
   navigationController.removeViewControoler(classes : viewControllersToRemove)
}
0 голосов
/ 06 февраля 2019

Предполагая, что так устроены контроллеры вида:

NavController1 - [seg 'Root View Controller'] -> VC1 - [sege 'Present Modally'] --

-> NavController2 - [переход 'Root View Controller'] -> VC2 - [переход "Push"] -> VC3 - [переход "Push"] -> VC4

Вы должны иметь возможность вернуться к VC1, отклонив VC2, VC3 или VC4.

// example for vc4
vc4.navigationController?.dismiss(animated: true, completion: nil)

Однако, если каждый из viewControllers был представленМодально, вы должны быть в состоянии пройти через presentingViewController, чтобы достичь VC1.

var currentVC: UIViewController? = self
var presentingVC: UIViewController? = currentVC?.presentingViewController
while presentingVC != nil && !(presentingVC is VC1) {
    currentVC?.dismiss(animated: true, completion: nil)
    currentVC = presentingVC
    presentingVC = currentVC?.presentingViewController
}

Надеюсь, что это поможет.

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