人類の多年の夢であったNSWindow
のタイトルバーのカスタマイズであるが、YosemiteになってついにオフィシャルなAPIが実装された。
YosemiteではApple製のアプリケーションほとんどにおいてデザインが一新され、かつてOS Xを特徴付けていたツルッとしたテクスチャは取り払われた。そしてウインドウのタイトルバーまでもが変わった。
ウインドウのタイトルバーは、OS XにおいてGUIアプリケーションの要である。タイトルバー自体がウインドウを移動するためのノブであり、左にはウインドウを操作するための赤・黄・青のコントロールが、中央にはウインドウのタイトルが表示される。ときにはツールバーと見かけ上くっついたりするが、いずれにしてもウインドウの中心はタイトルバーである。
そのタイトルバーをカスタマイズしたい、これは全人類が生まれながらに持っている当然の欲求である。そして、しかし、Appleは長年にわたってそういったAPIを提供してこなかった。ウインドウをウインドウたらしめるタイトルバーを、心ないデベロッパーが欲望のままに毀損することを許さないというように、禁断の果実を決して手放そうとはしなかった。それがYosemiteになって、Apple製のアプリケーションでさえ、一般的なタイトルバーのルールを破壊した。いまやタイトルバーには信号機のようなコントロールを残して、タイトルの代わりにツールバーが表示されたり、あるいはウインドウのコンテンツがそのまま表示されるようになった。これはいまやAppleだけの特権ではなく、ついにAPIが提供されたのである。
タイトルを非表示にする
OS X 10.10 YosemiteからNSWindow
に新しく追加されたプロパティvar titleVisibility: NSWindowTitleVisibility
を使うと、ウインドウのタイトルを非表示にできる。enum NSWindowTitleVisibility
は以下のように二つの値からなる。
enum NSWindowTitleVisibility : Int { case Visible case Hidden }
デフォルトは.Visible
であるが、ここでヘッダから.Hidden
のコメントを引用する。
The always hidden mode hides the title and moves the toolbar up into the area previously occupied by the title.
NSToolbar
がある場合にはタイトルがあった場所に移動するようだ。これによって、例えばSafariやカレンダーのように、タイトルバーの高さが少し高く、信号機のようなコントロールのすぐ右にツールバーがあるようなウインドウが作れる。NSWindow
にNSToolbar
を設定して、あとは以下のようなコードをNSWindowController
のfunc windowDidLoad()
などに実装する。
window?.titleVisibility = .Hidden
タイトルバーを装飾する
OS X 10.10 YosemiteではNSViewController
が大幅に強化され、iOSのUIViewController
から多くの思想を受け継いだ。そして同時にNSViewController
のサブクラスがいくつか追加された。その一つがNSTitlebarAccessoryViewController
である。
NSTitlebarAccessoryViewController
は、その名前が示す通り、タイトルバーを装飾するViewのControllerである。このViewControllerのview
プロパティが返すViewが、NSWindow
のタイトルバーに表示される。合わせてNSWindow
にも以下のようなプロパティやメソッドが追加されている。
var titlebarAccessoryViewControllers: [AnyObject] func addTitlebarAccessoryViewController(childViewController: NSTitlebarAccessoryViewController) func insertTitlebarAccessoryViewController(childViewController: NSTitlebarAccessoryViewController, atIndex index: Int) func removeTitlebarAccessoryViewControllerAtIndex(index: Int)
NSWindow
は複数のNSTitlebarAccessoryViewController
を順序付きで管理する。タイトルバーの中でどの部分に表示されるのかは、NSTitlebarAccessoryViewController
の持つvar layoutAttribute: NSLayoutAttribute
というプロパティで決定される。ただし現在の所NSLayoutAttribute
のうち有効な値は.Bottom
と.Right
のみであることがヘッダに書かれている。もちろんそれぞれに対応する位置は、タイトルバーの下と右である。
実際に表示するには以下のようなコードを、例えばNSWindowController
のfunc windowDidLoad()
に実装する。NSTitlebarAccessoryViewController
のインスタンスはStoryboardから生成している。
let accessory = storyboard?.instantiateControllerWithIdentifier("TitlebarAccessory") as NSTitlebarAccessoryViewController accessory.layoutAttribute = .Right window?.addTitlebarAccessoryViewController(accessory)
コンテンツをタイトルバーの領域まで拡げる
タイトルバーの位置までウインドウのコンテンツを表示するために、新たにvar titlebarAppearsTransparent: Bool
プロパティと、NSFullSizeContentViewWindowMask
定数が用意された。
titlebarAppearsTransparent
はタイトルバーの背景を透明にするかどうかを表す。NSFullSizeContentViewWindowMask
は、NSWindow
のvar styleMask: Int
プロパティに利用する定数で、タイトルバーの領域までをコンテンツの領域とすることを表現するものである。
NSFullSizeContentViewWindowMask
とNSScrollView
の組み合わせによって、タイトルバーの下にコンテンツが透けるような表現が可能になる。またNSFullSizeContentViewWindowMask
を設定した上でtitlebarAppearsTransparent
を真にすると、信号のようなコントロールだけのウインドウが作れるのだ。
window?.titleVisibility = .Hidden window?.styleMask |= NSFullSizeContentViewWindowMask window?.titlebarAppearsTransparent = true
伝統的手法
有史以来、NSWindow
のタイトルバーをカスタマイズすると言えば大きく二つの方法があり、ひとつはウインドウのコントロールまで完全に自作して自由に表示する方法、そしてもうひとつはwindow.contentView.superview
という風にNSWindow
の実装に依存してビューの階層を辿る方法である。現実的には主に後者が利用されることが多かったのではないだろうか。(NSThemeFrame
などで検索するとそういった方法を指し示すページが今も見つかるだろう。)
しかしOS X 10.10 Yosemiteでは、このビューの階層を辿る方法を使っていると"NSWindow warning: adding an unknown subview:"
というログが出力されるようになり、代わりにオフィシャルな方法が提供されることになった。このことはAppKitのリリースノートに記載されている。
まとめ
ここまでで、OS X 10.10 Yosemiteから追加されたAPIによって、柔軟にタイトルバーをカスタマイズできることがわかった。これらはもちろん組み合わせることもできる。例えばSafariでは、titlebarAppearsTransparent = true
とした上でlayoutAttribute = .Bottom
のNSTitlebarAccessoryViewController
を設定しているかもしれない。
また昨今噂されるUXKitでは、UXNavigationController
などUIKit由来の機能が存在するらしい。これらのNSWindowの新しいAPIを使って、例えばUINavigationBar
相当の機能をタイトルバーに押し込めることもできるのではないだろうか。
まだ見ぬOS X 10.11への期待を膨らませつつ、読者諸氏もNSWindow
のタイトルバーをカスタマイズしてみてほしい。こちらからは以上だ。
- 作者: 荻原剛志
- 出版社/メーカー: SBクリエイティブ
- 発売日: 2014/12/10
- メディア: 大型本
- この商品を含むブログ (2件) を見る