如何在 Mac OS 中创建模式滑出 window?

How to create modal slide-out window in Mac OS?

如何像这些屏幕截图中那样在 Xcode 中创建模式滑出 window/view "in-window"?

我已经尝试使用 "Authentication panel style" 动画创建新的 Window 控制器,但我只收到 Xcode 崩溃。

那种模态window叫做Sheet。使用 Storyboard segue 或以编程方式使用 NSViewController subclass 很容易获得此行为。下面的示例只是一个由 Xcode 创建的空白 OS X Cocoa 应用程序。 (我选择 Swift 作为语言,但它与 Objective-C 的工作方式相同。)

我添加到故事板的唯一内容是 sheet 视图的第二个视图控制器,以及每个视图上的标签和按钮。

显示 Sheet 带有故事板 Segue 的视图

选择 Sheet 视图控制器并显示“连接检查器”选项卡,将 "Presenting Segues - sheet" 连接到 "Display Sheet" 按钮。

将 "Received Actions - dismissController:" 连接到 "Close Sheet" 按钮。

就是这样!使这个例子工作不需要代码;只需构建 运行.


以编程方式显示 Sheet 视图

请注意,Xcode 使用两个自定义 class 文件创建默认项目。 Storyboard中,Application场景中表示AppDelegate.swift

我们不需要在此示例中使用 AppDelegate,但您可以使用它与主菜单或其他内容进行交互。

自定义 ViewController.swift 自定义 class 将用于呈现 sheet。它在 View Controller 场景中表示:


要以编程方式实例化 Sheet 视图控制器,它需要一个 Storyboard ID。在这里,我们将为其指定 ID“SheetViewController”。请注意,它仍然是一个普通的 NSViewController;对于此示例,我们不需要将其设为自定义 class,但您的应用程序可能希望:


在辅助编辑器中显示 ViewController.swift 文件,按住 Ctrl 键将连接从 "Display Sheet" 按钮拖到自定义 class 中。这将为我们命名为 "displaySheet":

的 @IBAction 函数创建存根代码

ViewController.swift 文件中,我们将 Sheet 视图控制器实现为惰性变量。它只会在第一次被访问时实例化一次。这将在第一次调用 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)
    }
}

与第一个示例一样,"Close Sheet" 按钮连接到 Sheet 视图控制器上的 "dismissController:" 操作。或者,您可以从 ViewController class:

中以编程方式调用该函数
self.dismissController(sheetViewController)

有关详细信息,请参阅 Apple "Sheets Programming Topics" 文档: https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/Sheets/Sheets.html

Objective-C版本:

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