Mac APP开发纯手工打造项目的初始化

132 阅读2分钟

新建项目后,删除MainMenu.xib 以及在info文件中删除相关文件的配置。

image.png

接下来我们在APPdelegate 中编写我们自己的window。

lazy var window: NSWindow = {
        let frame = CGRect(x: 0, y: 0, width: 1600, height: 800)
        let w = NSWindow(contentRect: frame, styleMask: [.titled, .resizable, .miniaturizable, .closable, .fullSizeContentView], backing: .buffered, defer: false)
        w.title = "Mac App"
        w.isRestorable = false
        w.center()
        w.backgroundColor = NSColor.systemGreen
        w.setFrame(frame, display: true)
        w.minSize = frame.size
        return w
    }()

在对应的代理方法中显示window

func applicationDidFinishLaunching(_ aNotification: Notification) {
        // Insert code here to initialize your application
        let frame = CGRect(x: 0, y: 0, width: 1600, height: 800)
        let w = NSWindow(contentRect: frame, styleMask: [.titled, .resizable, .miniaturizable, .closable, .fullSizeContentView], backing: .buffered, defer: false)
        w.title = "Mac App"
        w.isRestorable = false
        w.center()
        w.backgroundColor = NSColor.systemGreen
        w.setFrame(frame, display: true)
        w.level = NSWindow.Level(rawValue: Int(CGWindowLevelForKey(CGWindowLevelKey.overlayWindow)))
        w.minSize = frame.size
        
        mainWindowController = NSWindowController(window: w)
                mainWindowController.showWindow(nil)
                mainWindowController.window?.makeKeyAndOrderFront(nil)
                
                NSApplication.shared.mainWindow?.title = "Hello world"
                let scanViewCtrl = ScanViewController()
        w.contentViewController = scanViewCtrl
        
        addButtonToTitleBar()
    }

启动应用会发现只有在docker栏中有图标却不见窗口,通过再APPdelegate中打断点发现竟然没来到这里!!!

APPdelegate 代理是通过main文件加载的,可以推测到是main文件没有和APPdelegate文件绑定。、

但是在后续版本的模版工程工xcode隐藏了main文件的入口,用@main注解到APPdelegate上进行加载。貌似手工的不适用 。

自己手写main文件并和APPdelegate进行绑定

import Cocoa

func mainMenu() -> NSMenu {
    let    mainMenu             =    NSMenu()
    let    mainAppMenuItem      =    NSMenuItem(title: "Application", action: nil, keyEquivalent: "")
    let    mainFileMenuItem     =    NSMenuItem(title: "File", action: nil, keyEquivalent: "")
    mainMenu.addItem(mainAppMenuItem)
    mainMenu.addItem(mainFileMenuItem)
    
    let    appMenu              =    NSMenu()
    mainAppMenuItem.submenu     =    appMenu
    
    let    appServicesMenu      =    NSMenu()
    NSApp.servicesMenu          =    appServicesMenu
    appMenu.addItem(withTitle: "About", action: nil, keyEquivalent: "")
    appMenu.addItem(NSMenuItem.separator())
    appMenu.addItem(withTitle: "Preferences...", action: nil, keyEquivalent: ",")
    appMenu.addItem(NSMenuItem.separator())
    appMenu.addItem(withTitle: "Hide", action: #selector(NSApplication.hide(_:)), keyEquivalent: "h")
    appMenu.addItem({ ()->NSMenuItem in
        let m = NSMenuItem(title: "Hide Others", action: #selector(NSApplication.hideOtherApplications(_:)), keyEquivalent: "h")
        m.keyEquivalentModifierMask = NSEvent.ModifierFlags([.command, .option])
        return m
        }())
    appMenu.addItem(withTitle: "Show All", action: #selector(NSApplication.unhideAllApplications(_:)), keyEquivalent: "")
    
    appMenu.addItem(NSMenuItem.separator())
    appMenu.addItem(withTitle: "Services", action: nil, keyEquivalent: "").submenu    =    appServicesMenu
    appMenu.addItem(NSMenuItem.separator())
    appMenu.addItem(withTitle: "Quit", action: #selector(NSApplication.terminate(_:)), keyEquivalent: "q")
    
    let    fileMenu             =    NSMenu(title: "File")
    mainFileMenuItem.submenu    =    fileMenu
    fileMenu.addItem(withTitle: "New...", action: #selector(NSDocumentController.newDocument(_:)), keyEquivalent: "n")
    
    return mainMenu
}

autoreleasepool {
    let app =   NSApplication.shared //创建应用
    let delegate = AppDelegate()
    app.delegate =  delegate //配置应用代理
    app.mainMenu =  nil// mainMenu() //配置菜单,mainMenu 函数需要前向定义,否则编译错误
    app.run() //启动应用
}

然后再运行项目,🤩 成功了 。

最后个人建议不需要那么麻烦 ,直接使用系统模版进行启动就可以了 。