Frage

Ich habe eine Methode, die HTTP -Daten veröffentlicht und eine UialertView anzeigt, wenn ein Fehler vorliegt. Wenn ich mehrere HTTP -Posts habe, zeige ich für jeden Fehler mehrere UialertView.

Ich möchte nur eine UialertView anzeigen, wenn keine andere UialertView angezeigt wird. Wie kann ich das bestimmen?

War es hilfreich?

Lösung

Setzen Sie auf dem Objekt, das aufgerufen wird, einen IVAR, bevor Sie die Show -Methode auf Ihrem UialertView aufrufen.

...

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

...

Dann verwalten Sie in Ihrer Delegiertenmethode für die Warnung die Einstellung Ihres Flaggen -IVAR auf NO:

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

Wenn Sie möchten, dass die Warnungen nacheinander angezeigt werden, würde ich Benachrichtigungen veröffentlichen, um jede Nachricht einer Warteschlange hinzuzufügen und dann nur eine Nachricht von der Warteschlange zu nehmen, nachdem eine Warnung abgewiesen wurde.

Andere Tipps

Überprüfen Sie nicht einfach die sichtbare Eigenschaft, die von der UialertView -Klasse gepflegt wird?

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

Wenn Sie die anderen Alarmansichten steuern können, überprüfen Sie die visible Eigentum für jeden von ihnen.


In iOS 6 oder zuvor, wenn eine Warnung erscheint, wird es in eine _uialerToverlayWindow verschoben. Daher besteht eine ziemlich zerbrechliche Methode darin, alle Fenster durchzuführen und zu prüfen, ob UialertView -Unteransicht vorhanden ist.

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;

Dies ist undokumentiert, da es von der internen Ansichtshierarchie abhängt, obwohl Apple nicht darüber beschweren kann. Eine zuverlässigere, aber noch undokumentiertere Methode besteht darin, zu überprüfen wenn [_UIAlertManager visibleAlert] ist nil.

Diese Methoden können nicht überprüfen, ob eine UialertView von Springboard angezeigt wird.

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

Eine weitere Option, die in der gesamten App funktioniert und nicht das Gehen des View -Stacks ist, ist die Unterklasse UIAlertView zu MyUIAlertView, Fügen Sie eine statische (Klasse) Variable hinzu BOOL alertIsShowing, und überschreiben die -(void)show Wähler.

In Ihrem überschrieben show Selector, überprüfen Sie die alertIsShowing Variable. Wenn es YES Versuchen Sie dann nach einer Verzögerung erneut (Verwendung dispatch_after oder einstellen NSTimer). Wenn es NO, Rufen Sie an und rufen Sie an [super show] und zuweisen YES zu alertIsShowing; Wenn die Alarmansicht versteckt ist, stellen Sie fest alertIsShowing zurück zu NO (Sie müssen sich über den Umgang mit dem Delegierten umgehen.)

Schließlich gehen Sie durch und ersetzen Sie alle UIAlertView Beispiele mit MyUIAlertView.

Ich denke, es wird funktionieren:

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

Schnell:

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

Einige Notizen auf meiner Suche, die UialertView in der Aussichtshierarchie zu finden:

Ich habe versucht, alle durchzugehen [UIApplication sharedApplication].windows View ist rekursiv, konnte aber nichts finden.

Das windows Eigentum von UIApplication Dokumente stellt Folgendes fest:

Diese Eigenschaft enthält die UIWindow -Objekte, die derzeit der App zugeordnet sind. Diese Liste enthält keine vom System erstellten und verwalteten Windows, wie das Fenster zum Anzeigen der Statusleiste.

Das hat mir also klar gemacht, dass das der UIWindow wo UIAlertView Es könnte uns nicht einmal vorgestellt werden.

Es gibt jedoch auch eine Eigenschaft an UIApplication genannt keyWindow. Nachdem ich das durchschleifen konnte, fand ich private Klassen, die eine Alarmansicht bestimmen würden:

Auf iOS 7: _UIModalItemHostingWindow, _UIModalItemAlertContentView, _UIBackdropEffectView usw.

Auf iOS 8: _UIAlertControllerActionView, _UIAlertControllerShadowedScrollView, _UIBackdropView usw.

Ich konnte das nicht finden UIAlertView Dass ich vorgestellt habe, aber vielmehr ein Haufen Klassen, die es intern komponieren. Um die ursprüngliche Frage zu beantworten, Sie können wahrscheinlich die verwenden keyWindow Eigentum und prüfen Sie, ob Sie diese Klassen bemerken, Ihre App jedoch abgelehnt werden, wenn Sie versuchen, nach privaten Kursen zu suchen.

Für Leute, die neuer werden, ist neuer, UIAlertController Verfügbar für iOS 8 könnte den Verweis darauf erhalten, indem Sie:[UIApplication sharedApplication].keyWindow.rootViewController.presentedViewController.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top