2016-03-22 2 views
2

Я использую NSAlert для отображения сообщений об ошибках на главном экране моего приложения. В принципе, NSAlert это свойство моего основного контроллера представленияПроверьте, отображается ли в настоящее время NSAlert

class ViewController: NSViewController { 

    var alert: NSAlert? 

    ... 

} 

И когда я получаю несколько уведомлений, я показываю некоторые сообщения

func operationDidFail(notification: NSNotification) 
{ 
    dispatch_async(dispatch_get_main_queue(), { 

     self.alert = NSAlert() 
     self.alert.messageText = "Operation failed" 
     alert.runModal(); 
    }) 
} 

Теперь, если я получаю несколько уведомлений, тревога показывает вверх для каждого уведомления. Я имею в виду, он появляется с первым сообщением, я нажимаю «ОК», он исчезает, а затем снова появляется со вторым сообщением и т. Д. ... Это нормальное поведение.

То, что я хотел бы достичь, - это избежать этой последовательности сообщений об ошибке. Я на самом деле забочусь только о первом. Есть ли способ узнать, отображается ли в настоящее время мое предупреждение? Что-то вроде alert.isVisible как на iOS UIAlertView?

ответ

2

Из вашего кода, я подозреваю, что уведомление инициируется в фоновом потоке. В этом случае любые проверки того, что предупреждение отображается прямо сейчас, не помогут. Ваш код не будет запускать последующее выполнение блока до тех пор, пока первый блок не завершится, потому что метод runModal заблокирует, запустив NSRunLoop в модальном режиме.

Чтобы исправить вашу проблему, вы можете ввести свойство atom bool и проверить его до dispatch_async.

Objective-C Решение:

- (void)operationDidFail:(NSNotification *)note { 
    if (!self.alertDispatched) { 
     self.alertDispatched = YES; 
     dispatch_async(dispatch_get_main_queue(), ^{ 
      self.alert = [NSAlert new]; 
      self.alert.messageText = @"Operation failed"; 
      [self.alert runModal]; 
      self.alertDispatched = NO; 
     }); 
    } 
} 

же код с помощью Swift:

func operationDidFail(notification: NSNotification) 
{ 
    if !self.alertDispatched { 
     self.alertDispatched = true 
     dispatch_async(dispatch_get_main_queue(), { 
      self.alert = NSAlert() 
      self.alert.messageText = "Operation failed" 
      self.alert.runModal(); 
      self.alertDispatched = false 
     }) 
    } 
} 
+0

Это работает так, как я ожидаю, что это сработает, спасибо! – Randy

+0

@ Рэнди, добро пожаловать –

1

Вместо бега модальный вы могли бы попробовать

- beginSheetModalForWindow:completionHandler: 

источник: https://developer.apple.com/library/mac/documentation/Cocoa/Reference/ApplicationKit/Classes/NSAlert_Class/#//apple_ref/occ/instm/NSAlert/beginSheetModalForWindow:completionHandler:

В обработчике завершения установки оповещения свойство ноль. И показывается только предупреждение, если свойство alert равно nil (что будет каждый раз после отклонения предупреждения). EDIT: Я не вижу, чтобы в документации говорилось что-либо о любом флагом, который вы ищете.

+0

Спасибо, это работает хорошо. Я принял решение Бориса, хотя я хотел продолжать использовать 'runModal'. – Randy