Cocoa - 以编程方式呈现NSViewController

时间:2016-03-28 14:04:05

标签: xcode cocoa nsviewcontroller

一般来说,我们可以通过使用不同类型的NSStoryboardSeque(如Present,Show,Sheet等)从第一个视图控制器显示下一个视图控制器,但是,我们如何以编程方式实现相同的目标?。

与UIViewController比较,以presentViewController:animated:模式呈现视图控制器。 NSViewController有什么相同的方法吗?

提前致谢。

3 个答案:

答案 0 :(得分:2)

我使用的两种不同的演示类型是:

func presentViewControllerAsModalWindow(_ viewController: NSViewController)
func presentViewControllerAsSheet(_ viewController: NSViewController)

在做了一些更多的研究后,另一种方法是使用:

func presentViewController(_ viewController: NSViewController, animator: NSViewControllerPresentationAnimator)

吃一个自定义的演示动画师。在这里,您可以自由地做自己喜欢的事情:)

答案 1 :(得分:0)

1.使用StoryBoard标识符创建NSViewController实例

let theTESTVCor =  self.storyboard?.instantiateController(withIdentifier: "TESTVCor") as! NSViewController

2.Present In通过当前的NSViewController

theNSViewController.presentViewControllerAsModalWindow(theTESTVCor)

⚠️不要忘记在故事板中设置NSViewController的标识符

答案 2 :(得分:0)

如果您有一个视图控制器(呈现),那么它会像提供以下功能一样简单:

open func presentAsSheet(_ viewController: NSViewController)
open func presentAsSheet(_ viewController: NSViewController)
open func present(_ viewController: NSViewController, asPopoverRelativeTo positioningRect: NSRect, of positioningView: NSView, preferredEdge: NSRectEdge, behavior: NSPopover.Behavior)

如果需要在新窗口中显示视图控制器(NOT MODAL),则需要创建自己的NSWindowNSWindowController

let gridView = NSGridView(views: [
    [NSTextField(labelWithString: "label1"),NSTextField(labelWithString: "label2")],
    [NSTextField(labelWithString: "label3"),NSTextField(labelWithString: "label4")]
])
let viewController = NSViewController()
viewController.view = gridView
let window = NSWindow(contentViewController: viewController)
window.center()
let windowController = NSWindowController(window: window)
windowController.showWindow(nil)

解释:

故事板正在使用定序执行一些魔术。表演节目只是在对象"perform:"NSStoryboardShowSegueTemplate)上调用动作[NSApp sendAction:to:from]。此序列将为您创建NSWindowControllerNSWindow(私有方法windowWithContentViewController:),并在其顶部将layoutSubviews / resize并居中。不可思议的好处是可以自动保留窗口,因此您不必关心内存管理。

程序化调用示例(使用故事板通过viewController实例化windowController)

import Cocoa
import Contacts

class ShorteningHistoryWindowController : NSWindowController, Storyboarded {
    static var defaultStoryboardName = "ShorteningHistory"
}

struct ShorteningHistory {
    static let shared = ShorteningHistory()
    private var windowController : NSWindowController
    private init() {
        windowController = ShorteningHistoryWindowController.instantiate()
    }
    public func showHistory() {
        windowController.showWindow(self)
    }
}


extension Storyboarded where Self: NSWindowController {
    static var defaultStoryboardName: NSStoryboard.Name { return String(describing: self) }
    static var defaultIdentifer: NSStoryboard.SceneIdentifier {
        let fullName = NSStringFromClass(self)
        let className = fullName.components(separatedBy: ".")[1]
        return className
    }

    static func instantiate() -> Self {
        let storyboard = NSStoryboard(name: defaultStoryboardName, bundle: Bundle.main)
        guard let vc = storyboard.instantiateController(withIdentifier: defaultIdentifer) as? Self else {
            fatalError("Could not instantiate initial storyboard with name: \(defaultIdentifer)")
        }

        return vc
    }
}

PS:请不要忘记在情节提要中设置情节提要标识符