Ответ 1
Такое модальное окно называется Sheet. Это очень легко получить с помощью Storyboard Segue или программно с подклассом NSViewController
. Пример ниже - просто пустое приложение OS X Cocoa, созданное Xcode. (Я выбрал Swift в качестве языка, но он будет работать так же, как и Objective-C.)
Единственное, что я добавил в раскадровку, - это второй View Controller для представления листа, а также ярлык и кнопку на каждом представлении.
Отображение вида листа с раскадровкой Segue
С выбранным контроллером просмотра листа и отображенной вкладкой Инспектора подключений, подключите "Представление листов-листов" к кнопке "Отображение листа".
Подключите "Полученные действия - dismissController:" к кнопке "Закрыть лист".
Это! Там нет кода, необходимого для работы этого примера; просто построить и запустить.
Программный просмотр вида листа
Обратите внимание, что Xcode создает проект по умолчанию с двумя пользовательскими файлами классов. На раскадровке AppDelegate.swift представлен в сцене приложения:
Нам не нужно использовать AppDelegate для этого примера, но вы можете использовать его для взаимодействия с главным меню или для других целей.
Пользовательский ViewController.swift пользовательский класс будет использоваться для представления листа. Он представлен в сцене View Controller:
Чтобы создать экземпляр Sheet View Controller программно, ему нужен идентификатор раскадровки. Здесь мы дадим ему идентификатор "SheetViewController". Обратите внимание, что это все еще обычный NSViewController
; нам не нужно делать его настраиваемым классом для этого примера, но ваше приложение может захотеть:
Чтобы отобразить файл ViewController.swift в редакторе помощника, перетащите соединение из кнопки "Показать лист" в пользовательский класс, удерживая клавишу "Ctrl". Это создаст код заглушки для функции @IBAction, которую мы назовем "displaySheet":
В файле 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