160 Stimmen

Wie überprüft man, ob ein Ansichts-Controller modal präsentiert oder auf einem Navigations-Stack verschoben wurde?

Wie kann ich in meinem Ansichtscontrollercode zwischen folgenden Punkten unterscheiden:

  • modal präsentiert
  • auf dem Navigationsstapel verschoben

Sowohl presentingViewController als auch isMovingToParentViewController sind in beiden Fällen YES, daher nicht sehr hilfreich.

Was die Dinge kompliziert macht, ist, dass mein Elternansichtscontroller manchmal modal ist, auf dem der zu überprüfende Ansichtscontroller verschoben wird.

Es stellt sich heraus, mein Problem ist, dass ich meinen HtmlViewController in einem UINavigationController einbetten, der dann präsentiert wird. Deshalb haben meine eigenen Versuche und die guten Antworten unten nicht funktioniert.

HtmlViewController*     termsViewController = [[HtmlViewController alloc] initWithDictionary:dictionary];
UINavigationController* modalViewController;

modalViewController = [[UINavigationController alloc] initWithRootViewController:termsViewController];
modalViewController.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
[self presentViewController:modalViewController
                   animated:YES
                 completion:nil];

Ich denke, ich sollte meinem Ansichtscontroller besser mitteilen, wenn er modal ist, anstatt zu versuchen, es zu bestimmen.

138voto

ColdLogic Punkte 7061

Nehmen Sie es mit einer Prise Salz, nicht getestet.

- (BOOL)isModal {
     if([self presentingViewController])
         return YES;
     if([[[self navigationController] presentingViewController] presentedViewController] == [self navigationController])
         return YES;
     if([[[self tabBarController] presentingViewController] isKindOfClass:[UITabBarController class]])
         return YES;

    return NO;
 }

112voto

King-Wizard Punkte 15270

In Swift:

Fügen Sie einen Flag hinzu, um zu überprüfen, ob es sich um ein Modal handelt, anhand des Klassentyps:

// MARK: - UIViewController Implementierung

extension UIViewController {

    var isModal: Bool {

        let presentingIsModal = presentingViewController != nil
        let presentingIsNavigation = navigationController?.presentingViewController?.presentedViewController == navigationController
        let presentingIsTabBar = tabBarController?.presentingViewController is UITabBarController

        return presentingIsModal || presentingIsNavigation || presentingIsTabBar
    }
}

94voto

rmaddy Punkte 307342

Sie haben eine Methode übersehen: isBeingPresented.

isBeingPresented ist true, wenn der ViewController präsentiert wird, und false, wenn er gepusht wird.

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];

    if ([self isBeingPresented]) {
        // wird präsentiert
    } else if ([self isMovingToParentViewController]) {
        // wird gepusht
    } else {
        // einfach wieder anzeigen, weil ein anderer VC abgelehnt wurde
    }
}

45voto

Jonauz Punkte 4073

Swift 5
Hier ist die Lösung, die das Problem anspricht, das in den vorherigen Antworten erwähnt wurde, wenn isModal() true zurückgibt, wenn das UIViewController in einem präsentierten UINavigationController-Stack ist.

extension UIViewController {
    var isModal: Bool {
        if let index = navigationController?.viewControllers.firstIndex(of: self), index > 0 {
            return false
        } else if presentingViewController != nil {
            return true
        } else if navigationController?.presentingViewController?.presentedViewController == navigationController {
            return true
        } else if tabBarController?.presentingViewController is UITabBarController {
            return true
        } else {
            return false
        }
    }
}

Es funktioniert bisher für mich. Wenn einige Optimierungen, bitte teilen.

35voto

Jibeex Punkte 5059

self.navigationController != nil würde bedeuten, dass es sich im Navigationsstapel befindet.

Um den Fall zu behandeln, dass der aktuelle Ansichtscontroller verschoben wird, während der Navigationscontroller modal dargestellt wird, habe ich einige Codezeilen hinzugefügt, um zu überprüfen, ob der aktuelle Ansichtscontroller der Wurzelcontroller im Navigationsstapel ist.

extension UIViewController {
    var isModal: Bool {
        if let index = navigationController?.viewControllers.firstIndex(of: self), index > 0 {
            return false
        } else if presentingViewController != nil {
            return true
        } else if let navigationController = navigationController, navigationController.presentingViewController?.presentedViewController == navigationController {
            return true
        } else if let tabBarController = tabBarController, tabBarController.presentingViewController is UITabBarController {
            return true
        } else {
            return false
        }
    }
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X