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.

21voto

Kirill Punkte 630

Swift 5. Sauber und einfach.

if navigationController?.presentingViewController != nil {
    // Navigation Controller wird modal präsentiert
}

12voto

Charlton Provatas Punkte 2068

Swift 4

var isModal: Bool {
    return presentingViewController != nil ||
           navigationController?.presentingViewController?.presentedViewController === navigationController ||
           tabBarController?.presentingViewController is UITabBarController
}

9voto

Mehedi Hasan Punkte 329

Swift 5
Dieses praktische Erweiterung behandelt einige Fälle mehr als die vorherigen Antworten. Diese Fälle sind VC (View Controller) ist der Stamm-VC des App-Fensters, VC wird als Kind zum Eltern-VC hinzugefügt. Es versucht nur true zurückzugeben, wenn der ViewController modellhaft präsentiert wird.

extension UIViewController {
    /**
      gibt nur true zurück, wenn der ViewController präsentiert wird.
    */
    var isModal: Bool {
        if let index = navigationController?.viewControllers.firstIndex(of: self), index > 0 {
            return false
        } else if presentingViewController != nil {
            if let parent = parent, !(parent is UINavigationController || parent is UITabBarController) {
                return false
            }
            return true
        } else if let navController = navigationController, navController.presentingViewController?.presentedViewController == navController {
            return true
        } else if tabBarController?.presentingViewController is UITabBarController {
            return true
        }
        return false
    }
}

Dank an Jonauz's Antwort. Es gibt wieder Platz für weitere Optimierungen. Bitte diskutieren Sie über die Fälle, die im Kommentarbereich behandelt werden müssen.

4voto

Senõr Ganso Punkte 1674

Unter der Annahme, dass alle viewControllers, die Sie modal präsentieren, in einem neuen navigationController eingebettet sind (was Sie sowieso immer tun sollten), können Sie dieser Eigenschaft zu Ihrem VC hinzufügen.

private var wurdeGeschoben: Bool {
    guard let vc = navigationController?.viewControllers.first, vc == self else {
        return true
    }

    return false
}

3voto

Yevhen Dubinin Punkte 4517

Wie viele Leute hier vorschlagen, dass "Prüfungs"methoden nicht für alle Fälle gut funktionieren, habe ich in meinem Projekt eine Lösung gefunden, um das manuell zu verwalten. Der Punkt ist, wir verwalten normalerweise die Präsentation selbst - das ist nicht das, was hinter den Kulissen passiert und wir müssen introspektieren.

DEViewController.h Datei:

#import 

// Es ist eine Basisklasse für alle View-Controller innerhalb eines Projekts
@interface DEViewController : UIViewController 

// Geben Sie an, wie der ViewController von einem anderen ViewController präsentiert wird
// Der präsentierte ViewController sollte den Wert manuell zuweisen
typedef NS_ENUM(NSUInteger, SSViewControllerPresentationMethod) {
    SSViewControllerPresentationMethodUnspecified = 0,
    SSViewControllerPresentationMethodPush,
    SSViewControllerPresentationMethodModal,
};
@property (nonatomic) SSViewControllerPresentationMethod viewControllerPresentationMethod;

// andere Eigenschaften/Methoden...
@end

Die Präsentationen können jetzt auf diese Weise verwaltet werden:

Auf dem Navigationsstapel verschoben:

// DETestViewController erbt von DEViewController
DETestViewController *vc = [DETestViewController new];
vc.viewControllerPresentationMethod = SSViewControllerPresentationMethodPush;
[self.navigationController pushViewController:vc animated:YES];

Modal mit Navigation präsentiert:

DETestViewController *vc = [DETestViewController new];
vc.viewControllerPresentationMethod = SSViewControllerPresentationMethodModal;
UINavigationController *nav = [[UINavigationController alloc]
                               initWithRootViewController:vc];
[self presentViewController:nav animated:YES completion:nil];

Modal präsentiert:

DETestViewController *vc = [DETestViewController new];
vc.viewControllerPresentationMethod = SSViewControllerPresentationMethodModal;
[self presentViewController:vc animated:YES completion:nil];

Außerdem könnten wir in DEViewController eine Fallback-Option hinzufügen, um "prüfen" zu lassen, ob die oben genannte Eigenschaft gleich SSViewControllerPresentationMethodUnspecified ist:

- (BOOL)isViewControllerPushed
{
    if (self.viewControllerPresentationMethod != SSViewControllerPresentationMethodUnspecified) {
        return (BOOL)(self.viewControllerPresentationMethod == SSViewControllerPresentationMethodPush);
    }

    else {
        // Fallback auf Standard-Bestimmungsmethode
        return (BOOL)self.navigationController.viewControllers.count > 1;
    }
}

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