Puis-je pop à ViewController de spécifique?
-
26-09-2019 - |
Question
J'utilise application de navigation. Je pousse d'abord ViewController à la deuxième ViewController et de deuxième ViewController à la troisième ViewController. Maintenant, je veux pop du troisième ViewController First ViewController.I am effectuer cette tâche à l'aide du code, mais en dessous de mon application écrasements.
S'il vous plaît tout organisme me donner quelques directives appropriées. Je ne peux pas utiliser pop pour RootViewController parce qu'il est différent viewController. Merci à l'avance ...
En troisième ViewControler je l'ai écrit ceci:
FirstViewCtr *x=[[FirstViewCtr alloc] initWithNibName:@"FirstViewCtr" bundle:nil];
[self.navigationController popToViewController:x animated:NO];
La solution
En écrivant la première ligne que vous obtenez les indices de tous les contrôleurs de vue et de la deuxième ligne Vous arriverez à votre destination.
NSArray *array = [self.navigationController viewControllers];
[self.navigationController popToViewController:[array objectAtIndex:2] animated:YES];
Autres conseils
Une approche plus sûre:
- (void)turnBackToAnOldViewController{
for (UIViewController *controller in self.navigationController.viewControllers) {
//Do not forget to import AnOldViewController.h
if ([controller isKindOfClass:[AnOldViewController class]]) {
[self.navigationController popToViewController:controller
animated:YES];
return;
}
}
}
Swifty façon:
let dashboardVC = navigationController!.viewControllers.filter { $0 is YourViewController }.first!
navigationController!.popToViewController(dashboardVC, animated: true)
[self.navigationController popToViewController:[self.navigationController.viewControllers objectAtIndex:1] animated:YES];
Il est souvent plus important de le faire du haut de la pile, donc:
- (void)popToLast:(Class)aClass
{
for (int i=self.navigationController.viewControllers.count-1; i>=0; i--)
{
UIViewController *vc = self.navigationController.viewControllers[i];
if ([vc isKindOfClass:aClass])
{
[self.navigationController popToViewController:vc animated:YES];
break;
}
}
}
et vous appelez cela
popToLast:[SomeViewController class];
- (void) RetunToSpecificViewController{
for (UIViewController *controller in self.navigationController.viewControllers)
{
if ([controller isKindOfClass:[AnOldViewController class]])
{
//Do not forget to import AnOldViewController.h
[self.navigationController popToViewController:controller
animated:YES];
break;
}
}
}
rapide et sûr Swift 3 Version:
if let vc = navigationController.viewControllers.filter({ $0 is SpecificViewControllerClass }).first {
navigationController.popToViewController(vc, animated: true)
}
Votre code crée une nouvelle instance d'une vue qui n'a jamais été poussé sur la pile, puis tente de revenir à la pop ce contrôleur.
Si vous popping au contrôleur de vue racine, vous pouvez popToRootViewControllerAnimated:
utilisations
Si vous popping retour une distance connue, vous pouvez appeler popViewControllerAnimated:
plus d'une fois. Dans votre exemple, ce serait 2 contrôleurs donc aux appels. Vous pouvez faire la même chose en regardant dans viewControllers
pour le contrôleur 2 de la fin et popping à elle.
Les suggestions ci-dessus sont des solutions rapides. Un meilleur scénario de pratique serait de passer le contrôleur que vous souhaitez revenir le long de chaque contrôleur successif vous appuyez sur. Tout d'abord elle-même passe à la seconde, seconde passe que référence à troisième, troisième POP à la référence adoptée, qui est le premier.
En effet, vous créez un contrôleur temporaire racine. Vous pouvez sous-classe UINavigationController
et ajouter une propriété temporaryRoot
et une méthode de popToTemporaryRootViewControllerAnimated:
qui pop à votre racine temporaire et l'effacer. Lors de la première seconde de pousse, il se placerait aussi la racine temporaire afin que chaque contrôleur de la pile ne doit pas passer une référence autour. Vous devez ajouter des contrôles supplémentaires pour vous Incertain pop jamais passé le temporaryRoot sans l'effacer.
Après beaucoup d'efforts, quelqu'un a créé l'extension rapide de retour à un contrôleur de vue particulier à Swift 3.0.
extension UINavigationController {
func backToViewController(viewController: Swift.AnyClass) {
for element in viewControllers as Array {
if element.isKind(of: viewController) {
self.popToViewController(element, animated: true)
break
}
}
}
}
Méthode appel:
self.navigationController?.backToViewController(viewController: YourViewController.self)
Mise en œuvre et testé Swift 3.0
Voici la méthode qui peut utile pour naviguer à tout spécifique View Controller:
func poptoSpecificVC(viewController : Swift.AnyClass){
let viewControllers: [UIViewController] = self.navigationController!.viewControllers
for aViewController in viewControllers {
if aViewController.isKind(of: viewController) {
self.navigationController!.popToViewController(aViewController, animated: true)
break;
}
}
}
Utilisation:
self.poptoSpecificVC(viewController: createIntervalVC.self)
Je pense que .filter({...}).first
est un peu plus lent que .first(where: {...})
.
Aussi cela pourrait être écrit plus précisément à l'adresse que UIViewControllers.
extension UINavigationController {
func popToController<T: UIViewController>(_ type: T.Type, animated: Bool) {
if let vc = viewControllers.first(where: { $0 is T }) {
popToViewController(vc, animated: animated)
}
}
func popToControllerOrToRootControllerIfNotInTheStack<T: UIViewController>(_ type: T.Type, animated: Bool) {
if let vc = viewControllers.first(where: { $0 is T }) {
popToViewController(vc, animated: animated)
} else {
popToRootViewController(animated: animated)
}
}
}
Mise à jour pour Swift 3:
utilisé ci-dessous code simple, pour le bruit au contrôleur de vue spécifique;
for vc in self.navigationController!.viewControllers as Array {
if vc.isKind(of: YourViewControllerName) {
self.navigationController!.popToViewController(vc, animated: true)
break
}
}
Swift 4 Version
if let viewController = navigationController?.viewControllers.first(where: {$0 is YourViewController}) {
navigationController?.popToViewController(viewController, animated: false)
}
Vous pouvez spécifier un autre filtre .viewControllers.first
selon vos besoins permet de dire si par exemple vous avez même kind
des contrôleurs de vue résidant dans le contrôleur de navigation, vous pouvez spécifier un contrôle supplémentaire comme ci-dessous
if let viewController = navigationController?.viewControllers.first(where: {
if let current = $0 as? YourViewController {
return current.someProperty == "SOME VALUE"
}
return false } ) {
navigationController?.popToViewController(viewController, animated: false)
}
for controller in self.navigationController!.viewControllers as Array {
if controller.isKind(of: LoginVC.self) {
_ = self.navigationController!.popToViewController(controller, animated: true)
break
}
}
Fonction Mettre en UIViewController
1. il vérifie si UIViewController
spécifique existe dans UINavigationController
puis popToViewController
ou bien pushViewController
func navigate(_ navVC: AnyClass, pushVC: UIViewController) {
for obj in self.navigationController!.viewControllers {
if obj.isMember(of: navVC) {
self.navigationController!.popToViewController(obj, animated: true)
return
}
}
self.navigationController!.pushViewController(pushVC, animated: true)
}
Utilisez
self.navigate(ViewController.self, pushVC: self.storyboard?.instantiateViewController(withIdentifier: "ViewController") as! ViewController)
J'ai réponse ici. Ceci est 100% le code de travail pour Swift> 4.X