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)
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
}
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
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;
}
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
}
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
}
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
}
}
}
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
}
}
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.
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
}
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.
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.
vous pouvez le vérifier par window
propriété
if(viewController.view.window){
// view visible
}else{
// no visible
}
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");
}
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.
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
}