我使用标准的Xcode Swift模板(使用StoryBoards)创建了一个新的OS X Cocoa应用程序。
我已经在AppDelegate.swift中实现了一个IBAction来处理用户何时从“文件”菜单中选择“打开...”。如果所选文件是有效的图像文件,我创建一个NSImage,然后我想在ViewController的视图中显示。
@IBAction func openFile(sender: NSMenuItem) {
var openPanel = NSOpenPanel()
openPanel.beginWithCompletionHandler { (result :Int) -> Void in
if result == NSFileHandlingPanelOKButton {
if let imageURL = openPanel.URL {
let image = NSImage(contentsOfURL: imageURL)
// PRESENT image IN THE VIEW CONTROLLER
}
}
}
但是,我没有看到任何从AppDelegate连接到ViewController的方法。我只是设法找到了我应该看看self.window的建议!在AppDelegate中,但AppDelegate中没有窗口这样的东西。
谢谢, Michael Knudsen
答案 0 :(得分:13)
似乎AppDelegate只能连接到故事板中应用程序场景中的对象。如果您想获取ViewController,请从故事板中实例化它。
样品:
@IBAction func menuAction(sender: AnyObject) {
if let storyboard = NSStoryboard(name: "Main", bundle: nil) {
let controller = storyboard.instantiateControllerWithIdentifier("VC1") as NSViewController
if let window = NSApplication.sharedApplication().mainWindow {
window.contentViewController = controller // just swap
}
}
}
答案 1 :(得分:1)
我最近一直试图做同样的事情并设法通过在我的ViewController中创建@IBAction并控制拖动到我的应用程序的第一响应者(在菜单上方)来获取我需要更新视图的事件我的故事板视图)。
这是让我走出困境的问题: Application Menu Items Xcode
感谢Bluedome建议将其与First Responder的行动联系起来。
答案 2 :(得分:0)
如果你控制 - 从菜单拖动到第一个响应者(菜单上方的红色立方体)并选择一个现有的动作,那么你可以“响应链”到你的视图控制器。在我的情况下,我将Open附加到openFile,然后在我的视图控制器中添加了以下
override var acceptsFirstResponder: Bool {
return true
}
func openFile(sender: NSMenuItem) {
print("In view controller")
}
并且它在AppDelegate中没有任何更改的情况下工作。大多数菜单已经连接到第一响应者,因此只需在视图控制器中添加匹配的函数名称。
有关详细信息,请参阅此comment以及Event Handling Basics上的此文档。
答案 3 :(得分:0)
您可以访问mainWinow属性和contentViewController属性来创建对自定义ViewController类的引用。这类似于iOS rootViewController属性。
let rootViewController = NSApplication.shared().mainWindow?.windowController?.contentViewController as! ViewController
现在,您可以使用此引用从AppDelegate访问主故事板上的IBOutlets。
rootViewController.myTextView.textStorage?.mutableString.setString("Cats and dogs.")
这对于一个带有一个ViewController的Window的简单应用程序很有用。
答案 4 :(得分:0)
在Swift 5中并访问新的Windows数组:
@IBAction func menuAction(sender: AnyObject) {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let controller = storyboard.instantiateInitialViewController()
// The windows in the array are ordered from back to front by window level;
// thus, the last window in the array is on top of all other app windows.
// On app launch, UIApplication.shared.windows.count == 1 anyway.
if let window = UIApplication.shared.windows.last {
window.rootViewController = controller
}
}