Encuentra UIAlertView sin hacer reference a él iOS 7

Estaba usando un fragment de código en mi proyecto, respondió aquí: UIAlertView sin hacer reference a él

Aquí está el código:

+ (UIAlertView *) getUIAlertViewIfShown { if ([[[UIApplication shanetworkingApplication] windows] count] == 1) { return nil; } UIWindow *window = [[[UIApplication shanetworkingApplication] windows] objectAtIndex:1]; if ([window.subviews count] > 0) { UIView *view = [window.subviews objectAtIndex:0]; if ([view isKindOfClass:[UIAlertView class]]) { return (UIAlertView *) view; } } return nil; } 

Desafortunadamente, no funciona en iOS 7 y no puedo descartar una vista de alerta. Durante la debugging encontré que en el ciclo se muestra que la vista es de class UITransitionView . Bastante confuso porque no pude encontrar ninguna documentation rápida para esta class de vista.

¿Alguna idea de cómo puedo solucionar este problema?

En iOS7, la window de UIAlertView no aparece en -[UIApplication windows] . De hecho, el UIAlertView sí nunca se agrega a ninguna window, -[UIAlertView window] es siempre nil . En cambio, la vista de alerta gestiona una variedad de vistas no documentadas colocadas en -[UIApplication keyWindow] sin reference alguna a la vista de alerta.

Tu única opción real en iOS7 es realizar un seguimiento de tus vistas de alerta.

solución de iOS 7

 Class UIAlertManager = objc_getClass("_UIAlertManager"); UIAlertView *topMostAlert = [UIAlertManager performSelector:@selector(topMostAlert)]; 

No estoy seguro si es aprobable por AppStore, pero funciona.

Código de línea única UPD:

 UIAlertView *topMostAlert = [NSClassFromString(@"_UIAlertManager") performSelector:@selector(topMostAlert)]; 

Me he enfrentado a un problema similar y, en mi caso, las alertas se muestran desde el controller de instancia de vista diferente. Como Brian ya mencionó que la window de UIAlertView no aparece en [UIApplication windows] en iOS7.

Entonces, para seguir el siguiente enfoque, se puede seguir:

  1. Definir una constante BOOL en el Delegado de la aplicación:

     @property (nonatomic, assign) BOOL isAlertVisibleOnAppWindow; 
  2. Donde 'UIAlerView` está presente, verifique la existencia de la instancia anterior:

     AppDelegate *delegate = (AppDelegate *) [UIApplication shanetworkingApplication].delegate; if (!delegate.isAlertVisibleOnAppWindow) { delegate.isAlertVisibleOnAppWindow = YES; UIAlertView *alertView = [[UIAlertView alloc] init…//alert init code // Either handle alert cancel/completeion click here via blocks, or use alert delegates to reset the isAlertVisibleOnAppWindow BOOL variable to NO. } 

Esto podría ser útil para otras personas, pensó en compartir esto.

 UIAlertView *topMostAlert = [NSClassFromString(@"_UIAlertManager") performSelector:@selector(topMostAlert)]; 

Esto NO se permitirá publicar en Apple Store. Durante la validation de la compilation Xcode arrojará un error, algo así como: "acceso a un método no documentado .." Por lo tanto, no puede usarlo, sin embargo, este código funciona bien.

Puede registrarse en UIWindowDidBecomeVisibleNotification :

 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(aWindowBecameVisible:) name:UIWindowDidBecomeVisibleNotification object:nil]; 

y en aWindowBecameVisible, verifique la descripción de la window para _UIModalItemHostingWin :

 if ([[theWindow description] hasPrefix:@"<_UIModalItemHostingWin"]) { // This is the alert window }