wake-up-neo.com

Feststellen, ob die Ansicht von UIViewController sichtbar ist

Ich habe eine Registerkartenanwendung mit vielen Ansichten. Gibt es eine Möglichkeit herauszufinden, ob ein bestimmtes UIViewController derzeit innerhalb des UIViewController sichtbar ist? (auf der Suche nach einer Immobilie)

532
Rob Bonner

Die Fenstereigenschaft der Ansicht ist nicht null, wenn eine Ansicht derzeit sichtbar ist. Überprüfen Sie daher die Hauptansicht im Ansichts-Controller:

Durch Aufrufen der view -Methode wird die Ansicht geladen (falls sie nicht geladen ist), was unnötig und möglicherweise unerwünscht ist. Es ist besser, zuerst zu überprüfen, ob es bereits geladen ist. Ich habe den Aufruf von isViewLoaded hinzugefügt, um dieses Problem zu vermeiden.

if (viewController.isViewLoaded && viewController.view.window) {
    // viewController is visible
}

Oder wenn Sie über einen UINavigationController verfügen, der die Ansichtscontroller verwaltet, können Sie stattdessen dessen visibleViewController -Eigenschaft überprüfen.

In Swift unter iOS 9 (oder höher):

if viewController.viewIfLoaded?.window != nil {
    // viewController is visible
}
1024
progrmr

Hier ist die Lösung von @progrmr als UIViewController Kategorie:

// UIViewController+Additions.h

@interface UIViewController (Additions)

- (BOOL)isVisible;

@end


// UIViewController+Additions.m

#import "UIViewController+Additions.h"

@implementation UIViewController (Additions)

- (BOOL)isVisible {
    return [self isViewLoaded] && self.view.window;
}

@end
89
ma11hew28

Es gibt einige Probleme mit den oben genannten Lösungen. Wenn Sie beispielsweise UISplitViewController verwenden, gibt die Master-Ansicht immer true für zurück

if(viewController.isViewLoaded && viewController.view.window) {
    //Always true for master view in split view controller
}

Verwenden Sie stattdessen diesen einfachen Ansatz, der in den meisten, wenn nicht allen Fällen gut zu funktionieren scheint:

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

    //We are now invisible
    self.visible = false;
}

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

    //We are now visible
    self.visible = true;
}
45
vincentjames501

Für diejenigen unter Ihnen, die eine Swift 2.2 Version der Antwort suchen:

if self.isViewLoaded() && (self.view.window != nil) {
     // viewController is visible
}

und Swift:

if self.isViewLoaded && (self.view.window != nil) {
         // viewController is visible
}
42
Benjamin

Sie möchten die Eigenschaft UITabBarController von selectedViewController verwenden. Alle an einen Tab-Leisten-Controller angeschlossenen View-Controller verfügen über die Eigenschaft tabBarController, sodass Sie in jedem Code des View-Controllers Folgendes ausführen können:

if([[[self tabBarController] selectedViewController] isEqual:self]){
     //we're in the active controller
}else{
     //we are not
}
28
executor21

Bei einer modalen Über-Vollbild- oder Über-Kontext-Präsentation kann "sichtbar" bedeuten, dass sie sich über dem Ansichts-Controller-Stapel befindet oder nur sichtbar ist, aber von einem anderen Ansichts-Controller abgedeckt wird.

Um zu überprüfen, ob der Ansichts-Controller "ist der Ansichts-Controller von" ist sichtbar "ganz verschieden ist, sollten Sie den Ansichts-Controller-Stapel des Navigations-Controllers des Ansichts-Controllers überprüfen.

Ich habe ein Stück Code geschrieben, um dieses Problem zu lösen:

extension UIViewController {
    public var isVisible: Bool {
        if isViewLoaded {
            return view.window != nil
        }
        return false
    }

    public var isTopViewController: Bool {
        if self.navigationController != nil {
            return self.navigationController?.visibleViewController === self
        } else if self.tabBarController != nil {
            return self.tabBarController?.selectedViewController == self && self.presentedViewController == nil
        } else {
            return self.presentedViewController == nil && self.isVisible
        }
    }
}
25
WeZZard

Ich habe eine Swift -Erweiterung basierend auf der Antwort von @ progrmr erstellt.

Sie können auf einfache Weise überprüfen, ob ein UIViewController wie folgt auf dem Bildschirm angezeigt wird:

if someViewController.isOnScreen {
    // Do stuff here
}

Die Erweiterung:

//
//  UIViewControllerExtension.Swift
//

import UIKit

extension UIViewController{
    var isOnScreen: Bool{
        return self.isViewLoaded() && view.window != nil
    }
}
12
Besi

Für meine Zwecke, im Kontext eines Container View Controllers, habe ich das gefunden

- (BOOL)isVisible {
    return (self.isViewLoaded && self.view.window && self.parentViewController != nil);
}

funktioniert gut.

7
Chris Prince

Ich habe diese Funktion in UIViewController.h gefunden.

/*
  These four methods can be used in a view controller's appearance callbacks to determine if it is being
  presented, dismissed, or added or removed as a child view controller. For example, a view controller can
  check if it is disappearing because it was dismissed or popped by asking itself in its viewWillDisappear:
  method by checking the expression ([self isBeingDismissed] || [self isMovingFromParentViewController]).
*/

- (BOOL)isBeingPresented NS_AVAILABLE_IOS(5_0);
- (BOOL)isBeingDismissed NS_AVAILABLE_IOS(5_0);

- (BOOL)isMovingToParentViewController NS_AVAILABLE_IOS(5_0);
- (BOOL)isMovingFromParentViewController NS_AVAILABLE_IOS(5_0);

Möglicherweise können die oben genannten Funktionen erkennen, ob ViewController angezeigt wird oder nicht.

3
AechoLiu

wenn Sie einen UINavigationController verwenden und auch modale Ansichten verarbeiten möchten, verwende ich Folgendes:

#import <objc/runtime.h>

UIViewController* topMostController = self.navigationController.visibleViewController;
if([[NSString stringWithFormat:@"%s", class_getName([topMostController class])] isEqualToString:@"NAME_OF_CONTROLLER_YOURE_CHECKING_IN"]) {
    //is topmost visible view controller
}
3
MrTristan

Wenn Sie einen Navigationscontroller verwenden und nur wissen möchten, ob Sie sich im aktiven und obersten Controller, dann verwenden Sie:

if navigationController?.topViewController == self {
    // Do something
}

Diese Antwort basiert auf dem Kommentar von @ mattdipasquale .

Wenn Sie ein komplizierteres Szenario haben, lesen Sie die anderen Antworten oben.

3
phatmann

Der Ansatz, den ich für einen modalen Presented View-Controller verwendete, bestand darin, die Klasse des präsentierten Controllers zu überprüfen. Wenn der präsentierte Ansichtscontroller ViewController2 wäre, würde ich einen Code ausführen.

UIViewController *vc = [self presentedViewController];

if ([vc isKindOfClass:[ViewController2 class]]) {
    NSLog(@"this is VC2");
}
3
wigging

XCode 6.4, für iOS 8.4, ARC aktiviert

Offensichtlich viele Möglichkeiten, es zu tun. Die eine, die für mich gearbeitet hat, ist die folgende ...

@property(nonatomic, readonly, getter=isKeyWindow) BOOL keyWindow

Dies kann in jedem View-Controller folgendermaßen verwendet werden:

[self.view.window isKeyWindow]

Wenn Sie diese Eigenschaft in -(void)viewDidLoad aufrufen, erhalten Sie 0, und wenn Sie dies nach -(void)viewDidAppear:(BOOL)animated aufrufen, erhalten Sie 1.

Hoffe das hilft jemandem. Vielen Dank! Prost.

3
serge-k

sie können dies mit der Eigenschaft window überprüfen

if(viewController.view.window){

// view visible

}else{

// no visible

}
2
Saad Ur Rehman

Ich brauchte dies, um zu überprüfen, ob der Ansichtscontroller der aktuell angezeigte Controller ist. Ich habe überprüft, ob ein Ansichtscontroller vorhanden ist oder ob er über den Navigator übertragen wurde. Ich poste ihn, falls jemand eine solche Lösung benötigt:

if presentedViewController != nil || navigationController?.topViewController != self {
      //Viewcontroller isn't viewed
}else{
     // Now your viewcontroller is being viewed 
}
0
Abdoelrhman