OSX アプリでカスタムフォントを使う
Cocoa/Swift プログラミング
初めてまともに作った OS X アプリを @koogawa さんにテストしてもらったところ、いきなり画面に何も表示されない不具合に見舞われました。
原因はカスタムフォントの読み込みミスだったので、改めて正しい組み込み方を整理しておくことにしました。
発端
OS X アプリを作って @koogawaさん にアプリを使ってもらおうとしたところ、画面に何も表示されない不具合に見舞われてしまいました。
システムログを調べてもらったところ、次のログが出力されていることが分かりました。
Failed to set (contentViewController) user defined inspected property on (NSWindow): *** -[NSTextView setFont:]: nil NSFont given.
今回のアプリでは、バンドルにカスタムフォントを含めて使うようにしたつもりだったんですけど、どうやらバンドルからフォントを読み込むことができていなくて、戻り値で得られた nil
をそのまま NSTextView
の fontプロパティ
に代入したことが、画面全体が描画されない原因につながっていた様子でした。
フォントを取得できたときにだけ設定する
そこでまずは、なんらかの事情でフォントが取得できなかったとしても、適切に画面描画が行われるように修正します。
とは言ってもなにも難しいことはなく、バンドルからフォントを読み込んで nil
が得られたときに NSTextView
にフォントを設定しないようにします。
if let font = SystemFont.FontForCode.fontWithSize(15.0) {
self.codeTextView.font = font
}
今回は SystemFont型
の fontWithSize:メソッド
で、フォントが得られたらそれを、得られなければ nil
を返すようにしてあるので、ちゃんとフォントが得られたときだけ NSTextView
にフォントを設定します。
OS X アプリでバンドル内のフォントを使う
バンドルにカスタムフォントを含める
OS X アプリで、バンドル内にカスタムフォントを含めてアプリで使えるようにするには、まず、フォントデータを収めるリソースフォルダーを決めて、それを Info.plist
の Application fonts resource path
(ATSApplicationFontsPath
) に記載しておく必要がある様子でした。
<key>ATSApplicationFontsPath</key>
<string>Fonts</string>
ビルドフェイズでフォントをバンドルにコピーする
そうしたら、プロジェクト内にフォントファイルを保存して、それを Copy Files ビルドフェイズを作って Resources
フォルダー内の先ほど指定したフォルダーにコピーされるようにします。
Copy Files ビルドフェイズは、アプリのターゲット設定の Build Phases
画面にある
から行えます。
ここで Copy Files Phase
を選択して、作成された Copy Files フェイズを、既存の Copy Bundle Resources
フェイズの次あたりに移動します。
そして作成した Copy Files ビルドフェイズは、次の内容を設定します。
| 項目 | 値 |
|---|---|
| Destination | Resources |
| Subpath | Fonts |
| Copy on when installing | (チェックしない) |
設定項目の下にあるリストには、上記で指定した場所 (Resources/Fonts
にコピーするファイルを追加します。今回は、プロジェクトに追加しておいたカスタムフォントのファイルを指定することになります。
バンドルに含めたフォントを使う
ここまでできたら、これでバンドル内のフォントを OS X アプリ内で使えます。
let font = NSFont(name: "SourceCodePro-Regular", size: 10.0)!
フォント名にはファイル名でなく、フォントに割り当てられている PostScript 名
を指定します。この名前は OS X に付属の FontBook アプリで確認できます。