2016-09-21 1 views
0

Comme le titre l'indique, lorsque mon menu de barre d'état est ouvert et qu'un NSAlert est déclenché à partir d'un autre thread, l'interface utilisateur se bloque. Probablement parce que les deux choses tournent sur le thread principal. Mais puisque j'ai affaire à un NSAlert et un NSMenu, je n'ai pas ont pour les exécuter sur le fil principal?NSAlert apparaissant lorsque NSMenu est ouvert provoque l'arrêt de l'interface utilisateur

NSAlert code

func showWallpaperUpdateErrorAlert(messageText: String, informativeText: String) { 
    DispatchQueue.main.async { 
     NSApp.activate(ignoringOtherApps: true) 

     let updateErrorAlert = NSAlert() 
     updateErrorAlert.messageText = messageText 
     updateErrorAlert.informativeText = informativeText 
     updateErrorAlert.addButton(withTitle: "OK") 
     updateErrorAlert.runModal() 
    } 
} 

code NSMenu

func createStatusBarMenu() { 
    // Status bar icon 
    guard let icon = NSImage(named: "iconFrame44") 
     else { NSLog("Error setting status bar icon image."); return } 
    icon.isTemplate = true 
    statusBarItem.image = icon 

    // Create Submenu items 
    let viewOnRedditMenuItem = NSMenuItem(title: "View on Reddit...", action: #selector(viewOnRedditAction), keyEquivalent: "") 
    viewOnRedditMenuItem.target = self 

    let saveThisImageMenuItem = NSMenuItem(title: "Save This Image...", action: #selector(saveThisImageAction), keyEquivalent: "") 
    saveThisImageMenuItem.target = self 

    // Add to title submenu 
    let titleSubmenu = NSMenu(title: "") 
    titleSubmenu.addItem(descriptionMenuItem) 
    titleSubmenu.addItem(NSMenuItem.separator()) 
    titleSubmenu.addItem(viewOnRedditMenuItem) 
    titleSubmenu.addItem(saveThisImageMenuItem) 

    // Create main menu items 
    titleMenuItem = NSMenuItem(title: "No Wallpaperer Image", action: nil, keyEquivalent: "") 
    titleMenuItem.submenu = titleSubmenu 
    titleMenuItem.isEnabled = false 
    getNewWallpaperMenuItem = NSMenuItem(title: "Update Now", action: #selector(getNewWallpaperAction), keyEquivalent: "") 
    getNewWallpaperMenuItem.target = self 

    let preferencesMenuItem = NSMenuItem(title: "Preferences...", action: #selector(preferencesAction), keyEquivalent: "") 
    preferencesMenuItem.target = self 

    let quitMenuItem = NSMenuItem(title: "Quit Wallpaperer", action: #selector(quitAction), keyEquivalent: "") 
    quitMenuItem.target = self 

    // Add to main menu 
    let statusBarMenu = NSMenu(title: "") 
    statusBarMenu.addItem(titleMenuItem) 
    statusBarMenu.addItem(NSMenuItem.separator()) 
    statusBarMenu.addItem(getNewWallpaperMenuItem) 
    statusBarMenu.addItem(NSMenuItem.separator()) 
    statusBarMenu.addItem(preferencesMenuItem) 
    statusBarMenu.addItem(quitMenuItem) 

    statusBarItem.menu = statusBarMenu 

    statusBarMenu.delegate = self 
} 
+0

Bonjour, quelle est votre version d'OS X? Est-ce que c'est x 10,12 (Sierra)? – DoN1cK

+0

Oui, je suis sur Sierra. – yesthisisjoe

Répondre

1

Dans mon cas, la solution a été de rejeter le menu avant d'afficher l'alerte.

J'ai eu pour accéder au menu de la propriété de menuNSStatusItem et appelez cancelTrackingWithoutAnimation() (régulière cancelTracking() était pas aussi lisse). J'ai aussi dû faire cela en dehors du fil principal, pour une raison quelconque.

func showWallpaperUpdateErrorAlert(messageText: String, informativeText: String) { 
    statusBarItem.menu?.cancelTrackingWithoutAnimation() // This is new 

    DispatchQueue.main.async { 
     NSApp.activate(ignoringOtherApps: true) 

     let updateErrorAlert = NSAlert() 
     updateErrorAlert.messageText = messageText 
     updateErrorAlert.informativeText = informativeText 
     updateErrorAlert.addButton(withTitle: "OK") 
     updateErrorAlert.runModal() 
    } 
} 
+0

il fait le travail. – DoN1cK