DB1*_*DB1 5 macos cocoa nsviewcontroller osx-mavericks swift
这是一个很长的故事,但要缩短它; 我的第一个OSX应用程序是在Swift中使用故事板编写的(在Yosemite上)直到我发现我的(已完成)应用程序不会在Mavericks上运行.我需要在Mavericks上运行,所以我用NIB替换了故事板.
我的问题是与segues; 我正在使用'sheet type'segues在主视图控制器上显示工作表中的其他视图控制器.调用NSViewController的presentViewControllerAsSheet方法是一个很好的替代,因为它看起来一样,但是这个API是在Yosemite中引入的 - 所以我需要弄清楚如何为Mavericks做这个.
在主视图上的按钮操作中,我尝试使用beginSheet,如下所示:
secondViewController = SecondViewController(nibName: "SecondViewController", bundle: nil)
self.view.window?.beginSheet(secondViewController!view.window!, completionHandler: nil)
Run Code Online (Sandbox Code Playgroud)
但是第二个视图控制器的窗口在运行时为空.我已经尝试将新视图控制器作为子视图添加到应用程序窗口,但这是一个无法识别的选择器:
NSApplication.sharedApplication().windows[0].addSubView(secondViewController!.view)
Run Code Online (Sandbox Code Playgroud)
我搜索高低,以获取如何显示工作表的说明,我能找到的是:视图控制器可以拥有一张工作表吗?但我很遗憾地承认我不明白答案.有人可以帮我一些工作代码吗?我开始担心我正在尝试做一些与众不同的事情,但在约塞米蒂看起来不错,所以人们在优胜美地被释放之前是怎么做到的?
编辑 我仍然没有解决方案,所以我已经整理了一个小应用程序,显示我遇到的问题.
在AppDelegate.swift中:
class AppDelegate: NSObject, NSApplicationDelegate {
@IBOutlet weak var window: NSWindow!
var mainViewController: FirstView!
func applicationDidFinishLaunching(aNotification: NSNotification) {
mainViewController = FirstView(nibName:"FirstView", bundle: nil)
window.contentView = mainViewController.view
mainViewController.view.frame = (window.contentView as! NSView).bounds
}
}
Run Code Online (Sandbox Code Playgroud)
在FirstView.swift中(关联的NIB有一个'打开表'按钮)
class FirstView: NSViewController {
var secondView: SecondView?
var secondWindow: SecondWinCon?
override func viewDidLoad() {
super.viewDidLoad()
}
@IBAction func pressButton(sender: AnyObject) {
secondView = SecondView(nibName: "SecondView", bundle: nil)!
// method 1 - this is the behaviour I want (but it only works on OSX 10.10)
// presentViewControllerAsSheet(secondView!)
// method 2 - this just creates a floating window
// self.view.addSubview(secondView!.view)
// self.view.window?.beginSheet(secondView!.view.window!, completionHandler: nil)
// method 3 - this also creates a floating window
secondWindow = SecondWinCon(windowNibName: "SecondWinCon")
self.view.window?.beginSheet(secondWindow!.window!, completionHandler: nil)
}
}
Run Code Online (Sandbox Code Playgroud)
在SecondView.swift中(关联的NIB有一个'关闭'按钮)
class SecondView: NSViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
@IBAction func dismissPressed(sender: AnyObject) {
if (presentingViewController != nil) {
presentingViewController?.dismissViewController(self)
} else {
self.view.window?.sheetParent?.endSheet(self.view.window!)
}
}
}
Run Code Online (Sandbox Code Playgroud)
在SecondWinCon.swift中(关联的NIB为空)
class SecondWinCon: NSWindowController {
var secondView: SecondView?
override func windowDidLoad() {
super.windowDidLoad()
secondView = SecondView(nibName: "SecondView", bundle: nil)!
self.window?.contentView.addSubview(secondView!.view)
}
}
Run Code Online (Sandbox Code Playgroud)
如果取消注释方法1,您将看到我试图模拟的行为(记住它只适用于OS X 10.10).方法2或3显示第二个视图,但不显示为工作表.
我有同样的问题,发现可能不是与视图生命周期有关的问题.当我在viewDidLoad中调用presentViewControllerAsSheet时,不会显示工作表,您将在控制台中获取此信息:
无法在(NSWindow)上设置(contentViewController)用户定义的检查属性:presentViewController:animator :: View的视图不在窗口/视图层次结构中.
如果你在viewWillAppear或viewDidAppear中触发它,那完全没问题.
UPDATE
好的,让我们说清楚.
对于这个初始故事板,NSWindowController与视图控制器连接,认为这是一个根视图控制器(RootVC).在storyboard(SheetVC)中创建另一个所需的视图控制器作为工作表.在RootVC的viewWillAppear或viewDidAppear中,[self presentViewControllerAsSheet:SheetVC]
表格将显示,无需其他代码.
如果你来这里寻找解决方案,我几乎用方法 3 来实现。我错过的重要步骤是关闭 NSWindowController 的 NIB 中的“启动时可见”(它是 NSWindow 的一个属性)。在我的示例代码中,它位于 SecondWinCon.nib 中。