Обрабатывать событие закрытия окна в Swift

Как обработать событие закрытия окна с помощью Swift, например, чтобы спросить «Вы уверены, что хотите закрыть форму?»

введите описание изображения здесь

Форма будет закрыта в случае "да" и не закрыта в случае "нет". Отображение окна сообщения для меня не проблема.

viewWillDisappear() также работает для минимизации, но мне нужно только событие закрытия.

Спасибо.


person Evgeniy    schedule 19.10.2015    source источник


Ответы (4)


Как сказано выше, вы должны сделать ViewController NSWindowDelegate, но вы должны обрабатывать windowWillClose, а не windowShouldClose. windowShouldClose должен определить, может ли окно закрыться или нет, а не событие, когда окно фактически закрывается.

Я также обнаружил, что вам нужно настроить delegate в viewDidAppear, а не viewDidLoad. Для меня self.view.window еще не было определено в viewDidLoad.

override func viewDidAppear() {
    self.view.window?.delegate = self
}
person Thomas Alvarez    schedule 20.11.2015
comment
что делает self.view.window?.delegate = self именно plz? - person Nabeel Khan; 24.12.2016
comment
Устанавливает ViewController в качестве делегата для окна, которое представляет ViewController. Это позволяет ViewController, соответствующему протоколу NSWindowDelegate, фактически функционировать как делегат. - person Thomas Alvarez; 26.12.2016

У меня тоже был такой же запрос, я решил его, используя метод, подробно описанный здесь: Выйти из Cocoa Приложение при закрытии окна с помощью XCode Swift 3

Требуется три шага:

  1. Соответствуйте toNSWindowDelegate в своем классе ViewController.
  2. Переопределить метод viewDidAppear
  3. Добавить метод windowShouldClose

Добавленный код должен выглядеть так:

class ViewController: NSViewController, NSWindowDelegate {
    // ... rest of the code goes here
    override func viewDidAppear() {
        self.view.window?.delegate = self
    }
    func windowShouldClose(_ sender: Any) {
        NSApplication.shared().terminate(self)
    }
}
person Nabeel Khan    schedule 24.12.2016
comment
windowShouldClose — это метод делегата, который возвращает логическое значение, чтобы определить, следует ли разрешить закрытие окна или нет. Вы должны использовать windowWillClose. Вам также не нужно вручную завершать приложение в коде. Существует метод NSApplicationDelegate, который вы можете поместить в свой AppDelegate, чтобы приложение закрывалось, когда все окна закрыты. func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {return true} - person Thomas Alvarez; 26.12.2016

Вы можете использовать протокол NSWindowDelegate в своем классе ViewController. (См. документация здесь)

Чтобы ваш класс соответствовал протоколу:

class ViewController: NSObject, NSWindowDelegate

Чтобы определить, когда была нажата кнопка закрытия окна, используйте windowShouldClose:

Из документа:

Сообщает делегату, что пользователь попытался закрыть окно [...]

В этом методе вы можете использовать NSAlert, чтобы подсказать пользователю, действительно ли он хочет закрыть окно.

ИЗМЕНИТЬ (в ответ на комментарий @Mr Beardsley)

Чтобы сделать ViewController делегатом, используйте:

window.delegate = self

Где self — ViewController, а window — окно, которое вы используете. Вы можете поместить это в viewDidLoad:.

person Arc676    schedule 19.10.2015
comment
Спасибо за ответ. Я установил класс ViewController: NSObject, NSWindowDelegate и реализовал функцию windowShouldClose. Но это не работает. Я считаю, что должен установить свойство делегата для окна, но я не знаю, как это сделать. - person Evgeniy; 19.10.2015
comment
Чтобы установить делегата из вашего контроллера представления, просто сделайте что-то вроде: window.delegate = self In viewDidLoad (если вы используете 10.10 или более позднюю версию). Вам также понадобится ссылка или IBOutlet на рассматриваемое окно. - person Mr Beardsley; 19.10.2015

Просто добавьте эту функцию в AppDelegate...

func applicationShouldTerminateAfterLastWindowClosed (_ theApplication: NSApplication) -> Bool {
    return true
}
person Tourelou    schedule 13.03.2021