Ich habe 2 getrennte navigationcontrollers
, eine mit RootViewController
A und die andere mit RootViewController
B.
Ich kann ViewController
C auf den Navigationsstapel von A oder B schieben.
Frage: Wenn ich in ViewController
C bin, wie kann ich herausfinden, ob ich im Stack von A oder B bin?
Sie können die UINavigationController
-Eigenschaft von viewControllers
verwenden:
@property(nonatomic, copy) NSArray *viewControllers
Diskussion: Der Root-View-Controller befindet sich im Array auf Index 0, der Back-View-Controller auf Index n-2 und der Top-Controller auf Index n-1, wobei n die Anzahl der Elemente im Array ist.
https://developer.Apple.com/documentation/uikit/uinavigationcontroller
Sie können damit testen, ob der Root-View-Controller (der mit dem Array-Index 0) View-Controller A oder B ist.
Hier ist die Umsetzung der akzeptierten Antwort:
- (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;
}
}
Eine allgemeinere Implementierung der akzeptierten Antwort:
- (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;
}
Dies gibt den richtigen "Rückansicht-Controller" zurück, unabhängig davon, wo sich die aktuelle Klasse auf dem Navigationsstapel befindet.
Schnelle Implementierung von tjklemz code als Erweiterung:
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
}
}
Hier ist eine modifizierte Version von Prabhu Beemans Swift-Code, der ihn an Swift 3 anpasst:
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
}
}
Als UINavigationController
-Erweiterung:
extension UINavigationController {
func previousViewController() -> UIViewController? {
guard viewControllers.count > 1 else {
return nil
}
return viewControllers[viewControllers.count - 2]
}
}
Greifen Sie auf das n-2
-Element der viewControllers
-Eigenschaft zu, um auf den übergeordneten View-Controller zuzugreifen.
Sobald Sie diese Instanz haben, können Sie deren Typ überprüfen, indem Sie protokollieren, was aus der Funktion NSStringFromClass()
hervorgeht. Oder Sie können einen static const
-Bezeichnerstring in den Controllern A und B und eine Getter-Funktion, die den String ausgibt, behalten.
Schnelle Implementierung von @tjklemz-Code:
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
}
Verwenden Sie die navigationController
-Methode, um sie abzurufen. Siehe Dokumentation auf der Apple-Website .
navigationController Ein übergeordneter oder Vorfahr, bei dem es sich um eine Navigation handelt Regler. (schreibgeschützt)
@ property (nonatomic, readonly, keep) UINavigationController * navigationController
Diskussion Gibt nur einen Navigationscontroller zurück, wenn die Ansicht Controller ist in seinem Stapel. Diese Eigenschaft ist null, wenn eine Navigation Controller kann nicht gefunden werden.
Verfügbarkeit Verfügbar in iOS 2.0 und höher.
Weil tote Pferde gerne geschlagen werden :)
- (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];
}
Implementierung für Swift 2.2 - Fügen Sie dies in einer Erweiterung von UIViewController
hinzu. Sicher in dem Sinne, dass es nil
zurückgibt, wenn der Viewcontroller rootvc ist oder nicht in einem Navigationscontroller.
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
}
für Swift 3 Sie können dies tun:
var backtoViewController:UIViewController!
for viewController in (self.navigationController?.viewControllers)!.reversed() {
if viewController is NameOfMyDestinationViewController {
backtoViewController = viewController
}
}
self.navigationController!.popToViewController(backtoViewController, animated: true)
Sie müssen lediglich "NameOfMyDestinationViewController" durch viewController ersetzen, den Sie zurückgeben möchten.
Den vorherigen View-Controller zu finden ist einfach.
In Ihrem Fall, d. H., Sie befinden sich in C und benötigen B, [self.navigationController.viewControllers lastObject]
ist das, was Sie wollen.
Für A können Sie, da A der Root-View-Controller ist, einfach lastObject
durch firstObject
ersetzen.
Mit Swift mit Guard.
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]
}
}
Eine prägnantere schnelle Aufbringung:
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]
}
}
Meine Erweiterung, 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
}
}
}