检查NSAlert当前是否正在显示

时间:2016-03-22 14:38:14

标签: swift macos cocoa 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 个答案:

答案 0 :(得分:2)

从您的代码中,我怀疑通知是在后台线程中触发的。在这种情况下,任何警报立即可见的检查都无济于事。在第一个块完成之前,您的代码将不会启动后续块执行,因为runModal方法将阻塞,在模式模式下运行NSRunLoop

要解决您的问题,您可以引入原子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
        })
    }
}

答案 1 :(得分: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。 并且仅在警报属性为零时显示警报(这将在解除警报后第一次出现)。 编辑:我没有看到文档说出你要寻找的任何旗帜。