Domanda

Ho un metodo che i messaggi HTTP i dati e visualizza un UIAlertView se si verifica un errore. Se ho più post HTTP vi mostrerò UIAlertView multiplo per ogni errore.

Voglio mostrare un UIAlertView solo se non sta mostrando altri UIAlertView. Come è possibile determinare questo?

È stato utile?

Soluzione

sull'oggetto che chiamate impostato un Ivar prima di invocare il metodo show sul UIAlertView.

...

if (!self.alertShowing) {
    theAlert = [[UIAlertView alloc] initWithTitle:title message:details delegate:self cancelButtonTitle:nil otherButtonTitles:@"Okay", nil];
    self.alertShowing = YES;
    [theAlert show];
}

...

Poi, nel tuo metodo delegato per l'avviso gestire impostando la tua bandiera Ivar a nessuno:

- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
{
  ...
      self.alertShowing = NO;
}

Se si desidera che le segnalazioni per mostrare in sequenza, vorrei inviare notifiche per aggiungere ogni messaggio a una coda e poi prendere solo un messaggio dalla coda dopo un allarme è respinto.

Altri suggerimenti

Perché non solo controllare la proprietà visibile, gestito dalla classe UIAlertView?

if (_alert) //alert is a retained property
{
    self.alert = [[[UIAlertView alloc] initWithTitle:@"Your Title"
                                             message:@"Your message" 
                                            delegate:self
                                   cancelButtonTitle:@"Cancel"
                                   otherButtonTitles:@"OK"] autorelease];
}
if (!_alert.visible)
{
    [_alert show];
}

Se è possibile controllare le altre viste di avviso, controllare la proprietà visible per ciascuno di essi.


In iOS 6 o prima, quando viene visualizzato un avviso, sarà spostato in una _UIAlertOverlayWindow. Pertanto, un metodo piuttosto fragile è quello di scorrere tutte le finestre e verificare se ci sono subviews UIAlertView.

for (UIWindow* window in [UIApplication sharedApplication].windows) {
  NSArray* subviews = window.subviews;
  if ([subviews count] > 0)
    if ([[subviews objectAtIndex:0] isKindOfClass:[UIAlertView class]])
      return YES;
}
return NO;

Questo è documentato poiché dipende dalla gerarchia vista interna, anche se Apple non può lamentarsi di questo. Un metodo più affidabile, ma anche più documentato è quello di verificare se [_UIAlertManager visibleAlert] è pari a zero .

Questi metodi non possono controllare se viene mostrato un UIAlertView da SpringBoard.

- (BOOL)checkAlertExist {
    for (UIWindow* window in [UIApplication sharedApplication].windows) {
        NSArray* subviews = window.subviews;
        if ([subviews count] > 0) {
            for (id cc in subviews) {
                if ([cc isKindOfClass:[UIAlertView class]]) {
                    return YES;
                }
            }
        }
    }
    return NO;
}

Un'altra opzione che funziona attraverso l'intera applicazione e non coinvolge camminare lo stack vista è quello di creare una sottoclasse UIAlertView a MyUIAlertView, aggiungere una statica (classe) BOOL alertIsShowing variabile, e ignorare il selettore -(void)show.

Nel vostro selettore show override, controllare la variabile alertIsShowing. Se è YES quindi riprovare dopo un ritardo (uso dispatch_after o impostare un NSTimer). Se si tratta di NO, andare avanti e chiamare [super show] e assegnare YES a alertIsShowing; quando la vista avviso è nascosto, impostare alertIsShowing torna a NO (avrete bisogno di essere intelligente sulla gestione del delegato).

Infine, passare attraverso e sostituire tutte le istanze UIAlertView con MyUIAlertView.

Credo che funzionerà:

-(BOOL) doesAlertViewExist {
    if ([[UIApplication sharedApplication].keyWindow isMemberOfClass:[UIWindow class]])
    {
        return NO;//AlertView does not exist on current window
    }
    return YES;//AlertView exist on current window
}

Swift:

func showAlert(withTitle title: String, message: String, viewController: UIViewController) {
    if viewController.presentedViewController == nil { // Prevent multiple alerts at the same time
        let localizedTitle = NSLocalizedString(title, comment: "")
        let localizedMessage = NSLocalizedString(message, comment: "")
        let alert = UIAlertController(title: localizedTitle, message: localizedMessage, preferredStyle: .Alert)
        let action = UIAlertAction(title: "OK", style: .Default, handler: nil)
        alert.addAction(action)

        viewController.presentViewController(alert, animated: true, completion: nil)
    }
}
// initialize default flag for alert... If alert is not open set isOpenAlert as NO
BOOL isAlertOpen;
isAlertOpen = NO;
if (isAlertOpen == NO) {
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Alert" message:@"Alert is Open" delegate:self cancelButtonTitle:@"Okay!!" otherButtonTitles: nil];
    [alert show];
    // Now set isAlertOpen to YES
    isAlertOpen = YES;
}
else
{
    //Do something
}
+ (BOOL)checkAlertExist {

    for (UIWindow* window in [UIApplication sharedApplication].windows) {
        if ([window.rootViewController.presentedViewController isKindOfClass:[UIAlertController class]]) {
            return YES;
        }
    }
    return NO;
}

Alcune note sulla mia ricerca per trovare l'UIAlertView nella gerarchia della vista:

Ho provato a ciclo attraverso tutte le [UIApplication sharedApplication].windows vista del modo ricorsivo, ma non ho trovato nulla.

La proprietà windows di documenti UIApplication afferma quanto segue:

  

Questa proprietà contiene gli oggetti UIWindow attualmente associati   l'applicazione. La lista non include le finestre create e gestite dal   Sistema , ad esempio la finestra utilizzata per visualizzare la barra di stato.

Quindi questo mi ha fatto capire che la UIWindow in cui potrebbe essere situato UIAlertView non è nemmeno presentato a noi.

Tuttavia, v'è anche una proprietà su UIApplication chiamato keyWindow. Su scorrendo che, ho scoperto lezioni private che comporre una visione avviso:

In iOS 7:. _UIModalItemHostingWindow, _UIModalItemAlertContentView, _UIBackdropEffectView etc

Su iOS 8:. _UIAlertControllerActionView, _UIAlertControllerShadowedScrollView, _UIBackdropView etc

non riuscivo a trovare il UIAlertView che ho presentato, ma piuttosto, un gruppo di classi che la compongono internamente. Quindi, per rispondere alla domanda iniziale , probabilmente si può utilizzare la proprietà keyWindow e vedere se notate queste classi, ma la vostra applicazione potrebbe ottenere respinto per cercare di verificare la presenza di lezioni private.

Per la gente che utilizzano, il più recente, UIAlertController disponibile per iOS 8 potrebbe ottenere il riferimento ad essa tramite: [UIApplication sharedApplication].keyWindow.rootViewController.presentedViewController.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top