Question

J'ai une méthode que les données HTTP et messages affiche un UIAlertView s'il y a une erreur. Si je poste plusieurs HTTP je montrerai plusieurs UIAlertView pour chaque erreur.

Je veux montrer un UIAlertView que si on ne montre pas d'autres UIAlertView. Comment puis-je déterminer cela?

Était-ce utile?

La solution

Sur l'objet qui appelle définir une Ivar avant d'appeler la méthode show sur votre UIAlertView.

...

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

...

Ensuite, dans votre méthode de délégué pour l'alerte gérer la configuration de votre drapeau Ivar à pas:

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

Si vous voulez que les alertes pour afficher de manière séquentielle, je posterais des notifications pour ajouter chaque message à une file d'attente, puis prendre seulement un message de la file d'attente après une alerte est rejetée.

Autres conseils

Pourquoi ne pas simplement vérifier la propriété visible, entretenue par la 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];
}

Si vous pouvez contrôler les autres vues d'alerte, vérifiez la propriété visible pour chacun d'eux.


Dans iOS 6 ou avant, quand une alerte apparaît, il sera déplacé à un _UIAlertOverlayWindow. Par conséquent, une méthode assez fragile est de itérer toutes les fenêtres et vérifier s'il y a des sous-vues de 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;

Ceci est en situation irrégulière car elle dépend de la hiérarchie de vue interne, même si Apple ne peut pas se plaindre à ce sujet. Une méthode plus fiable, mais encore plus en situation irrégulière est de vérifier si [_UIAlertManager visibleAlert] est nul .

Ces méthodes ne peuvent pas vérifier si reçoit un UIAlertView de 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;
}

Une autre option qui fonctionne sur l'application entière et ne concerne pas la marche de la pile de vue est de sous-classe UIAlertView à MyUIAlertView, ajoutez une BOOL alertIsShowing variable statique (classe), et remplacer le sélecteur de -(void)show.

Dans votre sélecteur de show surchargée, vérifiez la variable alertIsShowing. Si elle est YES puis essayez à nouveau après un délai (utilisation dispatch_after ou placer un NSTimer). Si c'est NO, allez-y et appelez [super show] et assigner YES à alertIsShowing; lors du retour à alertIsShowing (vous aurez besoin d'être intelligent sur la manipulation du délégué) l'affichage des alertes est caché, définissez NO.

Enfin, passez et remplacer toutes les instances de UIAlertView avec MyUIAlertView.

Je pense que cela fonctionnera:

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

Quelques notes sur ma quête pour trouver la UIAlertView dans la hiérarchie de la vue:

J'ai essayé de boucle à travers toute la vue de récursive [UIApplication sharedApplication].windows mais n'a pas pu trouver quoi que ce soit.

La propriété windows de UIApplication docs stipule ce qui suit:

  

Cette propriété contient les objets UIWindow actuellement associés à   l'application. Cette liste ne comprend pas les fenêtres créées et gérées par le   Système , tel que la fenêtre utilisée pour afficher la barre d'état.

Alors cela me fait réaliser que le UIWindowUIAlertView pourrait se trouver est même pas présente à nous.

Cependant, il y a également une propriété sur UIApplication appelé keyWindow. Sur une boucle à travers, je trouve des classes privées qui composeraient une vue d'alerte:

Sur iOS 7:. _UIModalItemHostingWindow, _UIModalItemAlertContentView, _UIBackdropEffectView etc

Sur iOS 8:. _UIAlertControllerActionView, _UIAlertControllerShadowedScrollView, _UIBackdropView etc

Je ne pouvais pas trouver le UIAlertView que j'ai présenté, mais plutôt, un tas de classes qui la composent en interne. Donc, pour répondre à la question initiale , vous pouvez probablement utiliser la propriété keyWindow et voyez si vous remarquez ces classes, mais votre application pourrait obtenir rejeté pour essayer de vérifier les cours privés.

Pour les personnes utilisant la plus récente, UIAlertController disponible pour iOS 8 pourrait obtenir la référence à l'aide: [UIApplication sharedApplication].keyWindow.rootViewController.presentedViewController.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top