Comment dire si la vue de UIViewController est visible

j'ai une application tabbar, avec de nombreuses vues. Existe-t-il un moyen de savoir si un Contrôleuruiview est actuellement visible depuis le Contrôleuruiview? (recherche d'un bien)

480
demandé sur James Webster 2010-05-06 03:25:09

15 réponses

la propriété de fenêtre est non-nil si une vue est actuellement visible, alors vérifiez la vue principale dans le contrôleur de vue:

[EDIT] invoquer la méthode view fait charger la vue (si elle n'est pas chargée) ce qui est inutile et peut être indésirable. Il serait préférable de vérifier d'abord si elle est déjà chargée. J'ai ajouté l'appel à isViewLoaded pour éviter ce problème.

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

ou si vous avez un Controller UINavigationController gérant les contrôleurs de vue, vous pouvez vérifier sa propriété visibleViewController à la place.

également dans Swift sur iOS 9 (ou plus tard):

if viewController.viewIfLoaded?.window != nil {
    // viewController is visible
}
947
répondu progrmr 2017-11-10 18:35:00

Voici la solution de @progrmr comme un UIViewController catégorie:

// 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
86
répondu ma11hew28 2011-06-30 03:58:25

il y a quelques problèmes avec les solutions ci-dessus. Si vous utilisez, par exemple , un UISplitViewController , la vue maître retournera toujours true for

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

plutôt, adopter cette approche simple qui semble bien fonctionner dans la plupart, si pas tous les cas:

- (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;
}
41
répondu vincentjames501 2014-02-04 14:37:37

pour ceux d'entre vous qui cherchent une Swift 2.2 version de la réponse:

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

et Swift 3 :

if self.isViewLoaded && (self.view.window != nil) {
         // viewController is visible
}
38
répondu Benjamin 2016-10-07 13:11:55

vous voulez utiliser la propriété UITabBarController 's selectedViewController . Tous les contrôleurs de vue attachés à un contrôleur de barre d'onglets ont un jeu de propriétés tabBarController , de sorte que vous pouvez, à partir de l'intérieur du code de n'importe lequel des contrôleurs de vue:

if([[[self tabBarController] selectedViewController] isEqual:self]){
     //we're in the active controller
}else{
     //we are not
}
25
répondu executor21 2010-05-05 23:36:19

pour une présentation modale sur plein écran ou hors contexte," est visible " peut signifier qu'il est au-dessus de la pile du contrôleur de vue ou tout simplement visible mais couvert par un autre contrôleur de vue.

pour vérifier si le contrôleur de vue "est le contrôleur de vue supérieur" est très différent de "est visible", vous devez vérifier la pile de contrôleur de vue du contrôleur de navigation du contrôleur de vue.

j'ai écrit un morceau de code pour résoudre ce problème:

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
        }
    }
}
22
répondu WeZZard 2018-03-31 07:29:35

j'ai fait une extension rapide basée sur la réponse de @progrmr.

Il vous permet de vérifier facilement si un UIViewController est à l'écran comme suit:

if someViewController.isOnScreen {
    // Do stuff here
}

de L'extension:

//
//  UIViewControllerExtension.swift
//

import UIKit

extension UIViewController{
    var isOnScreen: Bool{
        return self.isViewLoaded() && view.window != nil
    }
}
12
répondu Besi 2015-05-20 08:36:22

pour mes besoins, dans le contexte d'un contrôleur de vue de conteneur, j'ai trouvé que

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

fonctionne bien.

7
répondu Chris Prince 2014-06-18 15:27:59

si vous utilisez un UINavigationController et que vous voulez aussi gérer les vues modales, voici ce que j'utilise:

#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
répondu MrTristan 2013-10-05 23:38:50

j'ai trouvé cette fonction dans UIViewController.h .

/*
  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);

Peut-être que les fonctions ci-dessus peuvent détecter le ViewController est apparu ou non.

3
répondu AechoLiu 2015-05-21 07:02:54

XCode 6.4, pour iOS 8.4, ARC activé

Évidemment beaucoup de façons de le faire. Celui qui a travaillé pour moi est le suivant...

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

peut être utilisé dans n'importe quel contrôleur de vue de la manière suivante,

[self.view.window isKeyWindow]

si vous appelez cette propriété dans -(void)viewDidLoad vous obtenez 0, puis si vous appelez cela après -(void)viewDidAppear:(BOOL)animated vous obtenez 1.

J'espère que ça aidera quelqu'un. Merci! Acclamation.

3
répondu serge-k 2015-09-04 08:16:10

vous pouvez le vérifier par window propriété

if(viewController.view.window){

// view visible

}else{

// no visible

}
2
répondu Saad Ur Rehman 2013-11-21 14:10:24

l'approche que j'ai utilisée pour un contrôleur modal de vue présentée était de vérifier la classe du contrôleur présenté. Si le contrôleur de vue présenté était ViewController2 alors j'exécuterais du code.

UIViewController *vc = [self presentedViewController];

if ([vc isKindOfClass:[ViewController2 class]]) {
    NSLog(@"this is VC2");
}
2
répondu wigging 2014-01-26 22:19:41

si vous utilisez un contrôleur de navigation et que vous voulez juste savoir si vous êtes dans le active et topmost contrôleur, puis utiliser:

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

cette réponse est basée sur le commentaire de @mattdipasquale .

Si vous avez un scénario compliqué, voir les autres réponses ci-dessus.

2
répondu phatmann 2017-05-23 12:18:24

j'avais besoin de ceci pour vérifier si le contrôleur de vue est le contrôleur de vue actuel, Je l'ai fait en vérifiant s'il y a un contrôleur de vue présenté ou poussé à travers le navigateur, Je l'affiche au cas où quelqu'un aurait besoin d'une telle solution:

if presentedViewController != nil || navigationController?.topViewController != self {
      //Viewcontroller isn't viewed
}else{
     // Now your viewcontroller is being viewed 
}
0
répondu Abdoelrhman 2018-08-22 04:50:16