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?
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!
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.
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.
Swift 2.0:
var navArray:Array = (self.navigationController?.viewControllers)!
navArray.removeAtIndex(navArray.count-2)
self.navigationController?.viewControllers = navArray
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
}
})
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
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];
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
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
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
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.