Cocoa - Present NSViewController programmatically

你说的曾经没有我的故事 提交于 2020-06-01 13:31:11

问题


Generally, We can able to display next view controller from first view controller by having different kind of NSStoryboardSeque like Present, Show, Sheet etc., But, How we can achieve the same programmatically?.

Comparing with UIViewController, presenting a view controller modally by presentViewController:animated:. Is there any same kind of approach for NSViewController?

Thanks in advance.


回答1:


The two different presentation types I use are:

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

After doing some more research another way to do using:

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

And eating a custom presentation animator. Here you have the freedom to do what you like :)




回答2:


1.Create a NSViewController instance with StoryBoard Identifier

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

2.Present In Via the current NSViewController

theNSViewController.presentViewControllerAsModalWindow(theTESTVCor)

⚠️ DO NOT FORGET to set the Identifier of the NSViewController in Storyboard




回答3:


If you have a view controller (presenting) than it's as simple as following function are provided:

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)

If you need to present a view controller in a new window (NOT MODAL) you need to create own NSWindow, NSWindowController

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)

EXPLANATION:

Storyboards are using seques to perform some magic. The show seque is simply calling action "perform:" on object NSStoryboardShowSegueTemplate ([NSApp sendAction:to:from]). This seque will create NSWindowController and NSWindow (private method windowWithContentViewController:) for you and on top it will layoutSubviews/resize and center the window. Magic bonus is self retaining the window so you don't care about memory management.

Example of programatic calling (using Storyboards to instantiate windowController with viewController)

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: Don't forget to set Storyboard Identifiers in Storyboard



来源:https://stackoverflow.com/questions/36263990/cocoa-present-nsviewcontroller-programmatically

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!