J'ai 2 séparés navigationcontrollers
, un avec RootViewController
A et l'autre avec RootViewController
B.
Je suis capable de pousser ViewController
C sur la pile de navigation de A ou de B.
Question: Quand je suis dans ViewController
C, comment puis-je savoir si je suis dans la pile appartenant à A ou à B?
Vous pouvez utiliser la propriété UINavigationController
'viewControllers
:
@property(nonatomic, copy) NSArray *viewControllers
Discussion: Le contrôleur de vue racine est à l'index 0 dans le tableau, le contrôleur de vue arrière à l'index n-2 et le contrôleur supérieur à l'index n-1, n étant le nombre d'éléments du tableau.
https://developer.Apple.com/documentation/uikit/uinavigationcontroller
Vous pouvez l'utiliser pour tester si le contrôleur de vue racine (celui dont l'indice de tableau est 0) est le contrôleur de vue A ou B.
Voici l'implémentation de la réponse acceptée:
- (UIViewController *)backViewController
{
NSInteger numberOfViewControllers = self.navigationController.viewControllers.count;
if (numberOfViewControllers < 2)
return nil;
else
return [self.navigationController.viewControllers objectAtIndex:numberOfViewControllers - 2];
}
- (UIViewController *)backViewController
{
NSInteger myIndex = [self.navigationController.viewControllers indexOfObject:self];
if ( myIndex != 0 && myIndex != NSNotFound ) {
return [self.navigationController.viewControllers objectAtIndex:myIndex-1];
} else {
return nil;
}
}
Une implémentation plus générale de la réponse acceptée:
- (UIViewController *)backViewController {
NSArray * stack = self.navigationController.viewControllers;
for (int i=stack.count-1; i > 0; --i)
if (stack[i] == self)
return stack[i-1];
return nil;
}
Cela retournera le "contrôleur de vue arrière" correct, indépendamment de l'emplacement de la classe actuelle dans la pile de navigation.
Implémentation rapide de tjklemz code en tant qu'extension:
extension UIViewController {
func backViewController() -> UIViewController? {
if let stack = self.navigationController?.viewControllers {
for(var i=stack.count-1;i>0;--i) {
if(stack[i] == self) {
return stack[i-1]
}
}
}
return nil
}
}
Voici une version modifiée de Code de Prabhu Beeman Swift qui l'adapte pour prendre en charge Swift 3:
extension UIViewController {
func backViewController() -> UIViewController? {
if let stack = self.navigationController?.viewControllers {
for i in (1..<stack.count).reverse() {
if(stack[i] == self) {
return stack[i-1]
}
}
}
return nil
}
}
En tant qu'extension UINavigationController
:
extension UINavigationController {
func previousViewController() -> UIViewController? {
guard viewControllers.count > 1 else {
return nil
}
return viewControllers[viewControllers.count - 2]
}
}
Accédez à l'élément n-2
de la propriété viewControllers
pour accéder au contrôleur de vue parent.
Une fois que vous avez cette instance, vous pouvez vérifier son type en enregistrant ce qui sort de la fonction NSStringFromClass()
. Ou vous pouvez conserver une chaîne d'identifiant static const
dans les contrôleurs A et B et une fonction de lecture qui imprime la chaîne.
Implémentation rapide du code @tjklemz:
var backViewController : UIViewController? {
var stack = self.navigationController!.viewControllers as Array
for (var i = stack.count-1 ; i > 0; --i) {
if (stack[i] as UIViewController == self) {
return stack[i-1] as? UIViewController
}
}
return nil
}
Utilisez la méthode navigationController
pour le récupérer. Voir documentation sur le site Apple .
navigationController Un parent ou un ancêtre qui est une navigation manette. (lecture seulement)
@property (nonatomic, en lecture seule, conserver) UINavigationController * navigationController
Discussion Renvoie uniquement un contrôleur de navigation si la vue le contrôleur est dans sa pile. Cette propriété est nil s'il s'agit d'une navigation contrôleur ne peut pas être trouvé.
Disponibilité Disponible dans iOS 2.0 et versions ultérieures.
Parce que les chevaux morts aiment être battus :)
- (UIViewController *)previousViewController
{
NSArray *vcStack = self.navigationController.viewControllers;
NSInteger selfIdx = [vcStack indexOfObject:self];
if (vcStack.count < 2 || selfIdx == NSNotFound) { return nil; }
return (UIViewController *)[vcStack objectAtIndex:selfIdx - 1];
}
Mise en œuvre pour Swift 2.2 - Ajoutez ceci dans une extension UIViewController
. Sécuritaire dans le sens où il retournera nil
si le contrôleur de vue est le rootvc ou non dans un contrôleur de navigation.
var previousViewController: UIViewController? {
guard let viewControllers = navigationController?.viewControllers else {
return nil
}
var previous: UIViewController?
for vc in viewControllers{
if vc == self {
break
}
previous = vc
}
return previous
}
pour Swift 3 vous pouvez le faire:
var backtoViewController:UIViewController!
for viewController in (self.navigationController?.viewControllers)!.reversed() {
if viewController is NameOfMyDestinationViewController {
backtoViewController = viewController
}
}
self.navigationController!.popToViewController(backtoViewController, animated: true)
Vous devez uniquement remplacer "NameOfMyDestinationViewController" par viewController que vous souhaitez renvoyer.
Trouver le contrôleur de vue précédent est simple.
Dans votre cas, c'est-à-dire que vous êtes en C et que vous avez besoin de B, [self.navigationController.viewControllers lastObject]
est ce que vous voulez.
Pour A, puisque A est le contrôleur de vue racine, vous pouvez simplement remplacer lastObject
par firstObject
pour obtenir.
Avec Swift utilisant la garde.
extension UIViewController {
func getPreviousViewController() -> UIViewController? {
guard let _ = self.navigationController else {
return nil
}
guard let viewControllers = self.navigationController?.viewControllers else {
return nil
}
guard viewControllers.count >= 2 else {
return nil
}
return viewControllers[viewControllers.count - 2]
}
}
Une déclaration Swift plus succincte:
extension UIViewController {
var previousViewController: UIViewController? {
guard let nav = self.navigationController,
let myIdx = nav.viewControllers.index(of: self) else {
return nil
}
return myIdx == 0 ? nil : nav.viewControllers[myIdx-1]
}
}
Mon extension, Swift 3
extension UIViewController {
var previousViewController: UIViewController? {
guard let controllers = navigationController?.viewControllers, controllers.count > 1 else { return nil }
switch controllers.count {
case 2: return controllers.first
default: return controllers.dropLast(2).first
}
}
}