web-dev-qa-db-fra.com

Suppression des contrôleurs de vue de la pile de navigation

J'ai une pile de navigation, avec par exemple 5 UIViewControllers. Je souhaite supprimer les troisième et quatrième contrôleurs de vue de la pile en cliquant sur un bouton du cinquième contrôleur de vue. Est-il possible de faire cela? Si c'est le cas, comment?

77
Jean Paul Scott

Utilisez ce code et profitez de:

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];

J'espère que ceci vous aidera.

Éditer: Swift Code

var navigationArray = self.navigationController?.viewControllers //To get all UIViewController stack as Array
navigationArray!.remove(at: (navigationArray?.count)! - 2) // To remove previous UIViewController
self.navigationController?.viewControllers = navigationArray!
144
Nit

Vous pouvez commencer par obtenir tous les contrôleurs de vue du tableau, puis après avoir vérifié avec la classe de contrôleur de vue correspondante, vous pouvez supprimer celui que vous voulez.

Voici un petit morceau de code:

NSArray* tempVCA = [self.navigationController viewControllers];

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

Je pense que cela facilitera votre travail.

46
Sourabh Bhardwaj

Swift 3 & 4/5

self.navigationController!.viewControllers.removeAll()

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

Swift 2.1

enlever tout:

self.navigationController!.viewControllers.removeAll()

enlever à l'index

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

Il y a un tas d'autres actions possibles comme removeFirst, range etc.

33
kuzdu

Swift 2.0:

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

Swift 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
Niklas

Utiliser la fonction setViewControllers à partir de UINavigationController est la meilleure solution. Il y a aussi le paramètre animated pour activer l'animation.

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

Exemple dans Swift pour la question

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)
}

J'ai essayé d'autres moyens comme [tempVC removeFromParentViewController];. Cela rend le comportement étrange, la navigation ViewController supprimée montrant toujours quand pop back comme rapporté par @ robin-ellerkmann

5
Megamind

Si vous essayez de passer à 2nd contrôleur de vue à partir de 5th contrôleur (en sautant 3ème et 4ème), vous voudriez utiliser [self.navigationController popToviewController:secondViewController].

Vous pouvez obtenir le secondViewController à partir de la pile de contrôleurs de navigation.

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

Utilisez ceci

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

Il s’occupera des ViewControllers de navigationController. viewControllers et aussi un navigationItems empilé dans navigationBar.

Remarque: Assurez-vous de l'appeler au moins après viewDidAppear

4
Nikola Markovic

Cette solution a fonctionné pour moi dans Swift 4:

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

votre index de contrôleur de vue actuel dans la pile est:

self.navigationController!.viewControllers.count - 1
2
babak

J'ai écrit une extension avec méthode qui supprime tous les contrôleurs situés entre root et top, sauf indication contraire.

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)
}

}

Si vous souhaitez utiliser la plage (par exemple: 2 à 5), vous pouvez simplement utiliser

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

Testé sur iOS 12.2, Swift 5

0
Adam

Swift 5, Xcode 10.

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

Assurez-vous d'appeler cette fonction utilitaire après viewDidDisappear () du contrôleur précédent ou viewDidAppear () du nouveau contrôleur.

0
Kedar Sukerkar