没有使用 Swift 的故事板或 xib 文件的 OSX 应用程序

Posted

技术标签:

【中文标题】没有使用 Swift 的故事板或 xib 文件的 OSX 应用程序【英文标题】:OSX application without storyboard or xib files using Swift 【发布时间】:2015-03-01 10:54:21 【问题描述】:

不幸的是,我在 Internet 上没有找到任何有用的东西 - 我想知道,在不使用 Swift 中的情节提要或 XIB 文件的情况下,我实际上必须键入哪些代码来初始化应用程序。我知道我必须有一个名为main.swift 文件。但我不知道在那里写什么(比如我需要自动释放池或类似的东西吗?)。例如,我将如何初始化NSMenu 以及如何将NSViewController 添加到活动窗口(ios 的类似.rootViewController 没有帮助)。感谢您的帮助;)

编辑: 我实际上不想在AppDelegate 前面使用@NSApplicationMain。我宁愿知道那里到底发生了什么,然后自己去做。

【问题讨论】:

我不知道你为什么要回避@NSApplicationMain,但这个问题在幕后确实具有很好的教育价值! 【参考方案1】:

如果您不想拥有 @NSApplicationMain 属性,请执行以下操作:

    有一个文件 main.swift

    添加以下***代码:

     import Cocoa
    
     let delegate = AppDelegate() //alloc main app's delegate class
     NSApplication.shared.delegate = delegate //set as app's delegate
     NSApplicationMain(CommandLine.argc, CommandLine.unsafeArgv) //start of run loop       
    
     // Old versions:
     //  NSApplicationMain(C_ARGC, C_ARGV)
     //  NSApplicationMain(Process.argc, Process.unsafeArgv);  
    

其余的应该在您的应用委托中。例如:

import Cocoa

class AppDelegate: NSObject, NSApplicationDelegate 
    var newWindow: NSWindow?
    var controller: ViewController?
    
    func applicationDidFinishLaunching(aNotification: NSNotification) 
        newWindow = NSWindow(contentRect: NSMakeRect(10, 10, 300, 300), styleMask: .resizable, backing: .buffered, defer: false)
        
        controller = ViewController()
        let content = newWindow!.contentView! as NSView
        let view = controller!.view
        content.addSubview(view)
        
        newWindow!.makeKeyAndOrderFront(nil)
    

那么你就有了一个 viewController

import Cocoa

class ViewController : NSViewController 
    override func loadView() 
        let view = NSView(frame: NSMakeRect(0,0,100,100))
        view.wantsLayer = true
        view.layer?.borderWidth = 2
        view.layer?.borderColor = NSColor.red.cgColor
        self.view = view
    

【讨论】:

我如何在窗口上显示几个视图控制器?或者我应该在需要时使用不同的窗口隐藏和显示?或者是否还有其他努力可以做到这一点? 我同意 leonardo 的观点,对于更复杂的东西,你应该使用 xibs——我不经常使用,但如果你卡在这个级别,我会这样做 抱歉,这不是“为我编写所有代码” - 您的问题已 100% 得到解答,您可以提出不同的具体问题或(最好)尝试一些教程 在 Swift 3.1 中是 func applicationDidFinishLaunching(_ notification: Notification)。纯粹的复制和粘贴让我有些困惑。 当我用 Xcode 9 尝试这个时,应用程序终止并抱怨它找不到 xib 文件。我在哪里告诉 NSApplication 不要使用 xib 文件?【参考方案2】:

上面的***代码示例不再适用于最新版本的 Xcode。而是使用这个:

import Cocoa

let delegate = AppDelegate() //alloc main app's delegate class
NSApplication.shared().delegate = delegate //set as app's delegate

let ret = NSApplicationMain(CommandLine.argc, CommandLine.unsafeArgv)

【讨论】:

在 Swift 4 中不再工作。我花了几个小时,仍然没有运气以编程方式创建一个纯 swift 的窗口。 Apple 做起来太难了(\阅读没有故事板的官方入门指南) @Kun 你找到解决方案了吗? @BohdanSavych 我做了,shared 现在是一个计算属性,所以在那之后去掉括号。【参考方案3】:

在 Swift 4 中,它再次略有变化,

主文件必须有

import Cocoa

let delegate = AppDelegate()
NSApplication.shared.delegate = delegate

NSApplicationMain(CommandLine.argc, CommandLine.unsafeArgv)

AppDelegate 必须是

import Cocoa


class AppDelegate: NSObject, NSApplicationDelegate 
    var newWindow: NSWindow?
    var controller: ViewController?

    func applicationDidFinishLaunching(_ aNotification: Notification) 
        newWindow = NSWindow(contentRect: NSMakeRect(10, 10, 300, 300), styleMask: .resizable, backing: .buffered, defer: false)

        controller = ViewController()
        let content = newWindow!.contentView! as NSView
        let view = controller!.view
        content.addSubview(view)

        newWindow!.makeKeyAndOrderFront(nil)
    

视图控制器是一样的

【讨论】:

对于像我这样希望制作显示标题框的窗口的人window = NSWindow(contentRect: winSize, styleMask: [.miniaturizable, .closable, .resizable, .titled], backing: .buffered, defer: false)【参考方案4】:

我使用的是 Swift 5,虽然我的应用程序可以使用来自 Noskcaj 答案的代码,但我从现有的 nib 文件中看到了一堆 [Nib Loading] Failed to connect... 错误。我通过在我的 main.swift 中使用它来修复它:

import Cocoa

autoreleasepool 
 let delegate = AppDelegate()
 // NSApplication delegate is a weak reference,
 // so we have to make sure it's not deallocated.
 withExtendedLifetime(delegate, 
     let application = NSApplication.shared
     application.delegate = delegate
     application.run()
     application.delegate = nil
 )

参考:https://***.com/a/54239088

【讨论】:

以上是关于没有使用 Swift 的故事板或 xib 文件的 OSX 应用程序的主要内容,如果未能解决你的问题,请参考以下文章

无法在 xCode 6 或更高版本中打开故事板或 xib 文件

PSCollectionView 的情节提要或 xib

如何在故事板或XIB中以编程方式分配uiview?

在故事板或 xib 中嵌入 cocos3d

swift3中的导航问题,带有没有故事板的.xib文件

如何在没有 xib 文件的情况下集成 iAD