Подтвердить что ты не робот

Удаление диспетчеров просмотра из стека навигации

У меня есть стек навигации, и, скажем, 5 UIViewControllers. Я хочу удалить 3-й и 4-й просмотрторы в стеке одним нажатием кнопки на 5-м контроллере. Можно ли сделать это? Если да, то как?

4b9b3361

Ответ 1

Используйте этот код и наслаждайтесь:

NSMutableArray *navigationArray = [[NSMutableArray alloc] initWithArray: self.navigationController.viewControllers];

// [navigationArray removeAllObjects];    // This is just for remove all view controller from navigation stack.
[navigationArray removeObjectAtIndex: 2];  // You can pass your index here
self.navigationController.viewControllers = navigationArray;
[navigationArray release];

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

Изменение: быстрый код

guard let navigationController = self.navigationController else { return }
var navigationArray = navigationController.viewControllers // To get all UIViewController stack as Array
navigationArray.remove(at: navigationArray.count - 2) // To remove previous UIViewController
self.navigationController?.viewControllers = navigationArray

Ответ 2

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

Вот небольшой фрагмент кода:

NSArray* tempVCA = [self.navigationController viewControllers];

for(UIViewController *tempVC in tempVCA)
{
    if([tempVC isKindOfClass:[urViewControllerClass class]])
    {
        [tempVC removeFromParentViewController];
    }
}

Я думаю, что это облегчит вашу работу.

Ответ 3

Свифт 3 и 4/5

self.navigationController!.viewControllers.removeAll()

self.navigationController?.viewControllers.remove(at: "insert here a number")

Swift 2.1

удалить все:

self.navigationController!.viewControllers.removeAll()

удалить по индексу

self.navigationController?.viewControllers.removeAtIndex("insert here a number")

Существует множество возможных действий, таких как removeFirst, range и т.д.

Ответ 4

Swift 2.0:

  var navArray:Array = (self.navigationController?.viewControllers)!
  navArray.removeAtIndex(navArray.count-2)
  self.navigationController?.viewControllers = navArray

Ответ 5

Свифт 5:

        navigationController?.viewControllers.removeAll(where: { (vc) -> Bool in
            if vc.isKind(of: MyViewController.self) || vc.isKind(of: MyViewController2.self) {
                return false
            }
            else {
                return true
            }
        })

Ответ 6

Использование функции setViewControllers из UINavigationController - лучший способ. Также есть animated параметр для включения анимации.

func setViewControllers(_ viewControllers: [UIViewController], animated: Bool)

Пример в стремительном вопросе

func goToFifthVC() {

    var currentVCStack = self.navigationController?.viewControllers
    currentVCStack?.removeSubrange(2...3)

    let fifthVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "fifthVC")
    currentVCStack?.append(fifthVC)

    self.navigationController?.setViewControllers(currentVCStack!, animated: true)
}

Я пробовал другие способы, такие как [tempVC removeFromParentViewController]; , Это делает странное поведение, удаленная навигация ViewController, все еще показывающая когда всплывающее окно, как сообщает @robin-ellerkmann

Ответ 7

Если вы пытаетесь перейти на контроллер 2-го представления с 5-го контроллера (пропуска 3-го и 4-го), вы хотели бы использовать [self.navigationController popToviewController:secondViewController].

Вы можете получить secondViewController из стека контроллера навигации.

secondViewController =  [self.navigationController.viewControllers objectAtIndex:yourViewControllerIndex];

Ответ 8

Использовать этот

if let navVCsCount = navigationController?.viewControllers.count {
    navigationController?.viewControllers.removeSubrange(Range(2..<navVCsCount - 1))
}

Это позаботится о ViewControllers из navigationController. viewControllers, а также элементы навигации, расположенные в навигационной панели.

Примечание. Обязательно вызывайте его хотя бы после viewDidAppear.

Ответ 9

Это решение работало для меня в Swift 4:

let VCCount = self.navigationController!.viewControllers.count
self.navigationController?.viewControllers.removeSubrange(Range(VCCount-3..<VCCount - 1))

Ваш текущий индекс контроллера представления в стеке:

self.navigationController!.viewControllers.count - 1

Ответ 10

Swift 5.1, Xcode 11

extension UINavigationController{
public func removePreviousController(total: Int){
    let totalViewControllers = self.viewControllers.count
    self.viewControllers.removeSubrange(totalViewControllers-total..<totalViewControllers - 1)
}}

Обязательно вызывайте эту служебную функцию после viewDidDisappear() предыдущего контроллера или viewDidAppear() нового контроллера

Ответ 11

Swift 5, Xcode 10.2

Я нашел этот подход простым, указав, какие контроллеры представления вы хотите удалить из стека навигации.

extension UINavigationController {

func removeViewController(_ controller: UIViewController.Type) {
    if let viewController = viewControllers.first(where: { $0.isKind(of: controller.self) }) {
        viewController.removeFromParent()
    }
}

}

Пример использования:

navigationController.removeViewController(YourViewController.self)

Ответ 12

Я написал расширение с методом, который удаляет все контроллеры между root и top, если не указано иное.

extension UINavigationController {
func removeControllers(between start: UIViewController?, end: UIViewController?) {
    guard viewControllers.count > 1 else { return }
    let startIndex: Int
    if let start = start {
        guard let index = viewControllers.index(of: start) else {
            return
        }
        startIndex = index
    } else {
        startIndex = 0
    }

    let endIndex: Int
    if let end = end {
        guard let index = viewControllers.index(of: end) else {
            return
        }
        endIndex = index
    } else {
        endIndex = viewControllers.count - 1
    }
    let range = startIndex + 1 ..< endIndex
    viewControllers.removeSubrange(range)
}

}

Если вы хотите использовать диапазон (например: от 2 до 5), вы можете просто использовать

    let range = 2 ..< 5
    viewControllers.removeSubrange(range)

Проверено на iOS 12.2, Swift 5