Показать NSWindowController из StatusMenu

У меня есть приложение, работающее из расширения в меню состояния.

У меня есть кнопка «Настройки», при нажатии на которую пользователь должен запускать определенный вид моей раскадровки.

Я пробовал много разных способов, открыть NSWindowController из NSMenu, Cocoa - Как вывести конкретное окно на передний план из StatusMenu.

Вот мой текущий код:

StatusMenu.swift

func showSettings() {

  var mainWindowController = MainWindowController()
  mainWindowController.showWindow(nil)

}

MainWindowController.swift

class MainWindowController: NSWindowController {

 override func windowDidLoad() {
   super.windowDidLoad()

   self.window?.center()
   self.window?.makeKeyAndOrderFront(nil)
   NSApp.activate(ignoringOtherApps: true)

   }

}

person Antoine    schedule 11.12.2017    source источник
comment
переместите объявление mainWindowController из вашего метода showSettings   -  person Leo Dabus    schedule 11.12.2017
comment
@LeoDabus только первая строка? Это не работает...   -  person Antoine    schedule 11.12.2017
comment
Вы уверены, что свойство окна не равно нулю?   -  person Leo Dabus    schedule 11.12.2017
comment
@LeoDabus да ... это потому, что я вызываю определенный NSWindowController в своей раскадровке? Я видел некоторые другие решения, требующие функции windowNibName.   -  person Antoine    schedule 11.12.2017


Ответы (1)


Опубликованный код имеет 2 потенциальных проблемы:

  1. MainWindowController.init реализован не NSWindowController, а NSObject, что означает, в отличие от NSViewControllers, это не ищет файл Nib с тем же именем. Использовать это:

    extension MainWindowController {
        convenience init() {
            self.init(windowNibName: .init(rawValue: "MainWindowController"))
        }
    }
    
  2. На результирующий экземпляр ссылаются из mainWindowController, но эта переменная имеет локальную область действия только для showSettings(). Это означает, что как только showSettings() будет выполнено, сборщик мусора снова освободит объект. Это все равно, что никогда не хранить его. Вам нужно сохранить постоянную ссылку в объекте, который живет или как глобальную переменную, например:

     // Assuming your StatusMenu instance is strongly referenced for the whole runtime
     class StatusMenu {
         var mainWindowController: MainWindowController?
         func showSettings() {
            self.mainWindowController = MainWindowController()
            self.mainWindowController?.showWindow(nil)
         }
     }
    
person ctietze    schedule 13.12.2017
comment
Я пытаюсь реализовать ваше решение, но не могу использовать .init... Это Swift 4? - person Antoine; 13.12.2017
comment
Да, в данном контексте это сокращение от NSNib.Name(rawValue:); в Swift 3 вы должны иметь возможность напрямую передавать строку. - person ctietze; 13.12.2017
comment
ОК, спасибо, я только что попробовал, и у меня есть ошибка: Не удалось преобразовать файл оконного пера MainWindowController, проблема в том, что мой наконечник находится в моей раскадровке? - person Antoine; 13.12.2017