Как создать модальное окно выключения в Mac OS?

Как я могу создать модальное выдвижное окно/представление "в окне" в XCode, как на этих скриншотах?

Я пытался создать новый контроллер Windows с анимацией "Стиль панели аутентификации", но затем получаю только сбои Xcode.

modal window

Ответы

Ответ 1

Такое модальное окно называется Sheet. Это очень легко получить с помощью Storyboard Segue или программно с подклассом NSViewController. Пример ниже - просто пустое приложение OS X Cocoa, созданное Xcode. (Я выбрал Swift в качестве языка, но он будет работать так же, как и Objective-C.)

Единственное, что я добавил в раскадровку, - это второй View Controller для представления листа, а также ярлык и кнопку на каждом представлении.

Отображение вида листа с раскадровкой Segue

С выбранным контроллером просмотра листа и отображенной вкладкой Инспектора подключений, подключите "Представление листов-листов" к кнопке "Отображение листа".

enter image description here

Подключите "Полученные действия - dismissController:" к кнопке "Закрыть лист".

enter image description here

Это! Там нет кода, необходимого для работы этого примера; просто построить и запустить.


Программный просмотр вида листа

Обратите внимание, что Xcode создает проект по умолчанию с двумя пользовательскими файлами классов. На раскадровке AppDelegate.swift представлен в сцене приложения:

enter image description here

Нам не нужно использовать AppDelegate для этого примера, но вы можете использовать его для взаимодействия с главным меню или для других целей.

Пользовательский ViewController.swift пользовательский класс будет использоваться для представления листа. Он представлен в сцене View Controller:

enter image description here


Чтобы создать экземпляр Sheet View Controller программно, ему нужен идентификатор раскадровки. Здесь мы дадим ему идентификатор "SheetViewController". Обратите внимание, что это все еще обычный NSViewController; нам не нужно делать его настраиваемым классом для этого примера, но ваше приложение может захотеть:

enter image description here


Чтобы отобразить файл ViewController.swift в редакторе помощника, перетащите соединение из кнопки "Показать лист" в пользовательский класс, удерживая клавишу "Ctrl". Это создаст код заглушки для функции @IBAction, которую мы назовем "displaySheet":

enter image description here

В файле ViewController.swift мы реализуем Sheet View Controller как ленивую переменную. Он будет создан только один раз, при первом обращении к нему. Это произойдет при первом вызове функции displaySheet.

//  ViewController.swift

import Cocoa

class ViewController: NSViewController {

    lazy var sheetViewController: NSViewController = {
        return self.storyboard!.instantiateControllerWithIdentifier("SheetViewController")
        as! NSViewController
    }()

    @IBAction func displaySheet(sender: AnyObject) {

        self.presentViewControllerAsSheet(sheetViewController)
    }
}

Версия Swift 4:

//  ViewController.swift

import Cocoa

class ViewController: NSViewController {

    lazy var sheetViewController: NSViewController = {
        return self.storyboard!.instantiateController(withIdentifier: NSStoryboard.SceneIdentifier(rawValue: "SheetViewController"))
        as! NSViewController
    }()

    @IBAction func displaySheet(sender: AnyObject) {

        self.presentViewControllerAsSheet(sheetViewController)
    }
}

Как и в первом примере, кнопка "Закрыть лист" подключена к действию "dismissController:" на контроллере вида листа. В качестве альтернативы, вы можете вызвать эту функцию программно из вашего класса ViewController:

self.dismissController(sheetViewController)

Для получения дополнительной информации обратитесь к документу Apple "Темы программирования листов":   https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/Sheets/Sheets.html

Ответ 2

Версия Objective-C:

- (IBAction)displaySheet:(id)sender {
    NSStoryboard *storyboard = [NSStoryboard storyboardWithName:@"Main" bundle: nil];
    NSViewController * vc = [storyboard instantiateControllerWithIdentifier:@"SheetViewController"];
    [self presentViewControllerAsSheet:vc];
}