[Xcode 8.1] サンプルコードからTouchBarのAPIを理解する#4 NSTouchBar CatalogのFancy Groupの構造と処理
本記事の目標:Fancy Groupのサンプルを理解する
こんにちは!モバイルアプリサービス部の加藤潤です。
前回に引き続きNSTouchBar Catalogを理解していきます。
今回はサンプルアプリの左側に表示されるメニューの内、Fancy Group
がどういう構造で成り立っているかを見ていきます。
実行結果
まず先にアプリとタッチバーの実行結果をご覧ください。
Fancy Group
ボタンが5つあり、「Button 1」, 「Button 2」, 「Button 3」, 「Button 4」をタップしても見た目上は何も起きませんが、
「Open Popover」をタップするとスライダーが表示されるようになっています。
また、スライダー左横の×ボタンをタップすると、スライダーが消えて再び5つのボタンが表示されます。
また、「Principal」のチェックを外すと全体が左に寄り、再びチェックを入れると元の位置に戻ることが確認できます。
Storyboardの構造
FancyGroupViewController.storyboard
の中がどういう構造になっているかを見てみましょう。
枠で囲った部分を見てください。
NSTouchBar
の中にNSGroupTouchBarItem
があり、その下にさらにNSTouchBar
があります。
この部分は前回ご紹介したGroupViewController.storyboard
と同じ作りになっています。
また、Button 1, Button 2, Button 3, Button 4についてもGroupViewController.storyboard
と同様にNSButton
が配置されています。
前回と異なるのはNSPopoverTouchBarItem
が配置されている点です。
NSPopoverTouchBarItem
の中にさらにNSTouchBar
が配置されていて、その中がNSTouchBarItem
、NSViewController
及びNSSlider
がぶら下がる形になっています。
NSPopoverTouchBarItem
のAttributes inspector
を見てみると、Shows Close Button
という項目があります。
この部分で×ボタンの表示/非表示を設定できるようです。試しにこの部分のチェックを外してみたら×ボタンが表示されませんでした。
非表示にするケースが思いつきませんが...
ソースコード
次にFancyGroupViewController.swift
を見てみましょう。
fileprivate extension NSTouchBarItemIdentifier { static let fancyGroup = NSTouchBarItemIdentifier("com.TouchBarCatalog.TouchBarItem.fancyGroup") } class FancyGroupViewController: NSViewController { // MARK: Action Functions @IBAction func buttonAction(_ sender: AnyObject) { let button = sender as! NSButton print("\(#function): button with title \"\(button.title)\" is tapped!") } @IBAction func sliderChanged(_ sender: AnyObject) { let slider = sender as! NSSlider print("\(#function): \"\(slider.intValue)\" !") } @IBAction func principalAction(_ sender: AnyObject) { guard let checkBox = sender as? NSButton else { return } let identifier = checkBox.state == NSOnState ? NSTouchBarItemIdentifier.fancyGroup : nil touchBar?.principalItemIdentifier = identifier } }
1〜3行目
NSTouchBarItemIdentifier
を定義しています。
ここで定義したcom.TouchBarCatalog.TouchBarItem.fancyGroup
という識別子がFancyGroupViewController.storyboard
内のNSGroupTouchBarItem
のIdentifierに設定されています。
8〜11行目
Button 1, Button 2, Button 3, Button 4がタップされた時にどのボタンがタップされたかを出力しているだけです。
13〜16行目
スライダーの値を変化させた時にその時の値(0~100の値)を出力しているだけです。
18〜23行目
「Principal」のチェックのON/OFF時に呼ばれるアクションメソッドです。チェックがONの場合はtouchBar?.principalItemIdentifier
に1〜3行目で定義したNSTouchBarItemIdentifier
(=NSGroupTouchBarItem
のIdentifier)を設定し、チェックがOFFの場合は当該プロパティにnil
を設定しています。
principalItemIdentifier
については、NSTouchBarのAPI Referenceに以下のように書かれています。
If you need to center an item in the Touch Bar, designate it as a principal item by assigning it to its bar’s principalItemIdentifier property. Do not hard-code spacing in an attempt to ensure an item is centered. If you want a group of items to appear centered in the Touch Bar, designate the group NSTouchBarItem as the principal item.
タッチバー内でアイテムをセンタリングしたい場合に使うプロパティのようです。「アイテムのグループをセンタリングしたい場合はNSGroupTouchBarItem
をprincipal itemに設定してください」とありますが、今回のサンプルがまさにそうなっていますね。
改めて最初の実行結果を見てみると、チェックが入った状態だと確かにグループ(ボタン全体が)中央に表示されています。チェックを外すと左寄りになるのはアイテムの配置がそうなっているからです。
まとめ
今回はFancy Groupのサンプルがどういう構造で成り立っているか、どういう作りになっているかを学びました。
今回のポイントは以下です。
NSPopoverTouchBarItem
を使うと一時的に表示するタッチバーを表現することができる。principalItemIdentifier
を使うと、タッチバー内でアイテムをセンタリングすることができる。