[Swift4/Cocoa] Storyboardとxibを使わずに初期ウィンドウを作成する

2018年6月24日(更新: 2018年6月24日)

Xcode で macOS 用のアプリ(Cocoa)のプロジェクトを作ると、Storyboard のチェックを外しても xib を使って最初のウィンドウ(NSWindow)を作る設定となっています。

今回は、Storyboard も xib も使わずにコードのみで初期ウィンドウを作成する方法について紹介します。

以下の手順は Cocoa Application のプロジェクトを Storyboard のチェックを外して作成した状態を想定しています。

xibファイルの紐付けを削除

Info.plist のプロパティである「Main nib file base name」を項目ごと削除します。

Info.plist の Main nib file base name

以上を削除後、プロジェクト内の MainMenu.xib は削除して構いません。

MainMenu.xib

手動でmain関数を編集

ウィンドウをプログラムのみで作成・表示する場合は main関数 を編集する必要があります。

Objective-C の使用時にファイルとして存在していた main関数 を含んだソースファイルは、Swift では @NSApplicationMain によって自動補完されています。

この自動補完の記述を削除して main.swift という名前のSwiftファイルをプロジェクトに追加することで、手動で main関数 を変更することができます。

そこで、まず AppDelegate.swift の @NSApplicationMain を以下の様に削除します。

import Cocoa

// @NSApplicationMain (この行を削除またはコメントアウト)
class AppDelegate: NSObject, NSApplicationDelegate {
    
    var window: NSWindow!
    
    func applicationDidFinishLaunching(_ aNotification: Notification) {

    ...

その後、プロジェクトに main.swift という名前でSwiftファイルを新規作成し、中身を以下のように書き換えます。

import Cocoa

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

ウィンドウの作成

実際にウィンドウを作成する処理です。AppDelegate 内に NSWindow を作成する処理を以下のように記述します。

import Cocoa

class AppDelegate: NSObject, NSApplicationDelegate {
    
    var window: NSWindow!
    
    func applicationDidFinishLaunching(_ aNotification: Notification) {
        window.makeKeyAndOrderFront(nil)
    }
    
    func applicationWillFinishLaunching(_ notification: Notification) {
        
        // ウィンドウの作成
        window = NSWindow(contentViewController: ViewController())
        window.title = "New Window"
        window.center()
    }

    // ウィンドウが閉じられたらアプリも終了する
    func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {
        return true
    }
}

NSWindow のインスタンス作成時に紐付けているクラスである ViewController の中身は以下の通りです。

ViewController.swift

import Cocoa

class ViewController : NSViewController {
    
    override func loadView() {
        self.view = NSView(frame: NSRect(x: 0, y: 0, width: 300, height: 200))
    }
    
    override func viewDidLoad() {
        print("viewDidLoad")
    }
}

ウィンドウ作成時に loadView が呼び出されます。ViewController には、初期状態で view が存在しないため、このメソッド内で作成しています。

これによって view が作成され、メソッド viewDidLoad が呼び出されます。ウィンドウのサイズは、この view に設定したサイズになります。

上記のようにファイルを編集後、プロジェクトを実行すると、以下のようなシンプルなウィンドウが表示されると思います。

xibを使わずに作成したウィンドウ

以上が Cocoa Application で Storyboard や xib を使わずにウィンドウを作成する方法です。

コメントを残す

メールアドレスが公開されることはありません。