OSX без файлов раскадровки или xib с использованием Swift

К сожалению, я не нашел ничего полезного в Интернете - я хотел знать, какой код мне нужно набирать для инициализации приложения без использования раскадровки или XIB файлов в Swift. Я знаю, что должен иметь файл .swift с именем main. Но я не знаю, что писать там (например, мне нужен autoreleasepool или что-то в этом роде?). Например, что бы я сделал для инициализации NSMenu и как бы добавить NSViewController в активное окно (iOS подобный .rootViewController не помогает). Спасибо за любую помощь;)

Изменить: На самом деле я не хочу использовать @NSApplicationMain перед AppDelegate. Я бы предпочел узнать, что именно происходит там, а затем сделать это сам.

Ответ 1

если вы не хотите иметь атрибут @NSApplicationMain, выполните следующие действия:

  • есть файл main.swift
  • добавить следующий код верхнего уровня:

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

остальное должно быть внутри вашего делегата приложения. например:.

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
    }
}

Ответ 2

Пример кода верхнего уровня выше не работает в последних версиях Xcode. Вместо этого используйте это:

import Cocoa

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

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

Ответ 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)
    }
}

Контроллер представления тот же

Ответ 4

Xcode 11/iOS13 - все изменилось

Короче говоря:

  • Вы должны удалить 2 строки в файле info.plist и создать экземпляр окна в новом классе SceneDelegate

Подробно:

Удалить эту строку в Info.plist...

enter image description here

... и эту строку (не так легко найти):

enter image description here

И здесь в новом SceneDelegate происходит новое волшебство для инициализации нашего собственного экземпляра UIWindow.

class SceneDelegate: UIResponder, UIWindowSceneDelegate {

var window: UIWindow?

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {

    // we try to cast the scene (UIScene) as UIWindowScene
    guard let windowScene = (scene as? UIWindowScene) else { return }

    // We create our window ourselfes and assign this windowScene to its property 'windowScene'
    window = UIWindow(frame: windowScene.coordinateSpace.bounds)
    window?.windowScene = windowScene

    // and then as always assign any rootViewController
    window?.rootViewController = WelcomeVC()

    // and make the window key and visible
    window?.makeKeyAndVisible()
}

}