Как я могу заставить свое приложение вести себя так, как будто я меняюсь? Приложение - агент (UIElement) во время выполнения с помощью Swift? - PullRequest
0 голосов
/ 26 июня 2018

Я кодирую приложение Mac, которое является NSPopover в правой части строки меню (Application is agent(UIElement) установлено на YES). Я разрешаю пользователю отсоединять всплывающее окно, щелкая и перетаскивая его вниз, что помещает приложение в окно. Это работает нормально; тем не менее, когда приложение перетаскивается из строки меню и превращается в окно, мне бы хотелось, чтобы значок моего приложения появлялся в доке, а также отображал специфичные для приложения меню в левой части строки меню, как будто Application is agent(UIElement) установлено на NO. И наоборот, когда окно закрывается и приложение возвращается к всплывающему окну в строке меню, мне бы хотелось, чтобы значок моего приложения исчез из док-станции и больше не отображал меню для приложений в левой части строки меню (Application is agent(UIElement) устанавливается обратно на YES).

С этот вопрос , я понимаю, что изменение Application is agent(UIElement) во время выполнения невозможно. Тем не менее, ответ дан в Objective-C, и последняя функция, кажется, устарела начиная с OS X 10.9. Как сделать так, чтобы мое приложение работало так же, как и изменение Application is agent(UIElement) во время выполнения с помощью Swift?

Я знаю, что показ значка приложения / меню строки меню происходит в windowDidBecomeMain, а скрытие значка приложения / меню строки меню происходит в windowWillClose.

Спасибо.

Ответы [ 2 ]

0 голосов
/ 28 июня 2018

Кроме того, вам может потребоваться сделать что-то подобное ниже, если у вас возникнут проблемы с отображением меню и значка док-станции после переключения на обычный режим.В старых версиях Mac OS это определенно требовалось.

        // needed to activate menu
    NSArray *dockAppA = [NSRunningApplication runningApplicationsWithBundleIdentifier:@"com.apple.loginwindow"];
    NSRunningApplication *dock = [dockAppA firstObject];
    [dock activateWithOptions:NSApplicationActivateIgnoringOtherApps];

    NSArray *dockAppB = [NSRunningApplication runningApplicationsWithBundleIdentifier:@"myAppBundleIdentifier"];
    NSRunningApplication *myApp = [dockAppB firstObject];
    [myApp activateWithOptions:NSApplicationActivateIgnoringOtherApps];
0 голосов
/ 27 июня 2018

Потребовалось много проб и ошибок, но я наконец понял это.Вместо использования Application is agent(UIElement) вы используете NSApp.setActivationPolicy.Это теперь мой код.В приложении делегат:

var isWindow = false

class AppDelegate: NSObject, NSApplicationDelegate, NSPopoverDelegate {

    let statusItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.squareLength)
    let popover = NSPopover()

    func applicationDidFinishLaunching(_ aNotification: Notification) {
        // Insert code here to initialize your application

        NSApp.setActivationPolicy(.accessory)

        if let button = statusItem.button {
            button.image = NSImage(named: "StatusBarImage")
            button.action = #selector(togglePopover(_:))
        }
        popover.contentViewController = MainViewController.loadController()
        popover.delegate = self
        popover.animates = false
        popover.behavior = .transient
    }

    @objc func togglePopover(_ sender: Any?) {
        if popover.isShown == true {
            popover.performClose(sender)
        } else if detachedWindowController.window!.isVisible {
            detachedWindowController.window?.setIsVisible(false)
            isWindow = true
        } else if isWindow == true {
            detachedWindowController.window?.setIsVisible(true)
        } else {
            if let button = statusItem.button {
                popover.show(relativeTo: button.bounds, of: button, preferredEdge: NSRectEdge.minY)
            }
        }
    }

    lazy var detachedWindowController: DetachedWindowController = {
        let detachedWindowController = DetachedWindowController(windowNibName: "DetachedWindowController")
        detachedWindowController.contentViewController = MainViewController.loadController()
        return detachedWindowController
    }()

    func popoverShouldDetach(_ popover: NSPopover) -> Bool {
        return true
    }

    func detachableWindow(for popover: NSPopover) -> NSWindow? {
        return detachedWindowController.window
    }
}

В DetachedWindowController:

class DetachedWindowController: NSWindowController, NSWindowDelegate {

    @IBOutlet var detachedWindow: NSWindow!

    override func windowDidLoad() {
        super.windowDidLoad()

        detachedWindow.delegate = self
    }

    func windowWillClose(_ notification: Notification) {
        isWindow = false
        NSApp.setActivationPolicy(.accessory)
    }

    func windowDidBecomeMain(_ notification: Notification) {
        if NSApp.activationPolicy() == .accessory {
            NSApp.setActivationPolicy(.regular)
        }
    }
}
...