没有使用 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 应用程序的主要内容,如果未能解决你的问题,请参考以下文章