life change ios uiview uiviewcontroller

ios - change - viewcontroller swift



Cómo saber si la vista de UIViewController es visible (15)

Aquí está la solución de @ progrmr como una categoría de UIViewController :

// 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

Tengo una aplicación de barra de pestañas, con muchas vistas. ¿Hay alguna manera de saber si un UIViewController en particular está visible actualmente dentro de UIViewController? (buscando una propiedad)


Desea utilizar la propiedad selectedViewController del UITabBarController . Todos los controladores de vista conectados a un controlador de barra de pestañas tienen un tabBarController propiedades tabBarController , por lo que puede, desde cualquiera de los códigos de los controladores de vista:

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


El enfoque que utilicé para un controlador de vista presentado modal fue verificar la clase del controlador presentado. Si el controlador de vista presentado fuera ViewController2 entonces ejecutaría algún código.

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


Encontré esas funciones en UIViewController.h .

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

Tal vez las funciones anteriores puedan detectar si el ViewController aparece o no.


Hay un par de problemas con las soluciones anteriores. Si está utilizando, por ejemplo, un UISplitViewController , la vista maestra siempre devolverá verdadero para

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

En su lugar, tome este enfoque simple que parece funcionar bien en la mayoría, si no en todos los casos:

- (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; }


Hice una extensión rápida basada en la respuesta de @ progrmr.

Le permite verificar fácilmente si un UIViewController está en la pantalla de esta manera:

if someViewController.isOnScreen { // Do stuff here }

La extensión:

// // UIViewControllerExtension.swift // import UIKit extension UIViewController{ var isOnScreen: Bool{ return self.isViewLoaded() && view.window != nil } }


La propiedad de la ventana de la vista es nula si una vista está actualmente visible, así que verifique la vista principal en el controlador de vista:

[EDITAR] Invocar el método de view hace que la vista se cargue (si no está cargada), lo cual no es necesario y puede ser indeseable. Sería mejor verificar primero si ya está cargado. He agregado la llamada a isViewLoaded para evitar este problema.

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

O si tiene un UINavigationController que administra los controladores de vista, puede verificar su propiedad visibleViewController su lugar.

Además, en Swift en iOS 9 (o posterior):

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


Necesitaba esto para verificar si el controlador de vista es el controlador visto actualmente, lo hice comprobando si hay un controlador de vista presentado o empujado a través del navegador, lo estoy publicando en caso de que alguien necesite una solución de este tipo:

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


Para aquellos de ustedes que buscan una versión Swift 2.2 de la respuesta:

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

y Swift 3 :

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


Para la presentación modal en pantalla completa o en contexto, "es visible" podría significar que está en la parte superior de la pila del controlador de vista o simplemente visible pero cubierto por otro controlador de vista.

Para verificar si el controlador de vista "es el controlador de vista superior" es bastante diferente de "es visible", debe verificar la pila del controlador de vista del controlador de navegación de vista.

Escribí un trozo de código para resolver este problema:

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 } } }


Para mis propósitos, en el contexto de un controlador de vista de contenedor, he encontrado que

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

funciona bien.


Puedes comprobarlo por propiedad de window

UIViewController *vc = [self presentedViewController]; if ([vc isKindOfClass:[ViewController2 class]]) { NSLog(@"this is VC2"); }


Si está utilizando un UINavigationController y también quiere manejar vistas modales, lo que uso es lo siguiente:

#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 }


Si está utilizando un controlador de navegación y solo quiere saber si está en el controlador activo y en el más alto , utilice:

if(viewController.view.window){ // view visible }else{ // no visible }

Esta respuesta se basa en el comentario de @mattdipasquale .

Si tiene un escenario más complicado, vea las otras respuestas anteriores.


XCode 6.4, para iOS 8.4, ARC habilitado

Obviamente hay muchas formas de hacerlo. El que me ha funcionado es el siguiente ...

[self.view.window isKeyWindow]

Esto se puede utilizar en cualquier controlador de vista de la siguiente manera,

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

Si llama a esta propiedad en -(void)viewDidLoad obtiene 0, luego si llama a esta propiedad después de -(void)viewDidAppear:(BOOL)animated obtiene 1.

Espero que esto ayude a alguien. ¡Gracias! Aclamaciones.