2010-12-22

ドロワー (NSDrawer) の使い方 - ラベル検索の実装 #2 (MacBloggerGlass)

ラベルの一覧を表示する UI として、ドロワーを使うことにした。ドロワーとは、アプリウィンドウの端に(大抵は左右のどちらか)付加的に表示できるウィンドウのことだ。通常のアプリウィンドウと同じく、様々なビューを置くことができる。

最近の Mac OS X 用アプリではあまり見かけなくなった(少々古臭い) UI だが、表示中はメインウィンドウにくっついており見失うこともないし、不要なときは隠しておけばメインウィンドウ上のレイアウトを圧迫することもない。

MacBloggerGlass のメインウィンドウは記事一覧表示とその内容表示で、すでに 2 分割(2 ペイン)しているが、ここにラベル一覧表示領域を追加するとさらに分割することになってしまう。その方が使いやすいならそうするが、まずは表示領域の分割ではなく、必要な時だけ領域を追加する方式で試してみることにした。

Interface Builder での操作

Cocoa アプリにドロワーを追加するには、ライブラリツールから Windows グループにある Windows and Drawer (右のスクリーンショットを参照)をドラッグしドキュメントウィンドウにドロップする。

ライブラリツール上は 1 つのオブジェクトのように置かれているが、ドキュメントウィンドウにドロップすると以下の 3 つのオブジェクトが現れる(下のスクリーンショット参照。)。

  • Window
  • Drawer Content View
  • Drawer

この 3 つのオブジェクトは、ドロップされた状態ですでに互いに関連づけられている。具体的には Drawer に備わったアウトレットのうち、parentWindow が Window に、contentView が Drawer Content View にそれぞれ結びつけられている。

大抵の場合、アプリウィンドウはプロジェクトを作ったときから (MainMenu.xib 内に) 存在しているため、上記の Window オブジェクトは不要だ。当然、削除することになるが、そのときは Drawer オブジェクトの parentWindow を適切に設定しなければならない。

Drawer オブジェクト(の parentWindow)にアプリのウィンドウを結びつけるには、Ctrl キーを押しながら Drawer オブジェクトからアプリウィンドウまでドラッグする。アプリウィンドウ上に接続するアウトレットの候補が現れるので、parentWindow を選ぶ。

この Interface Builder のドキュメントにも書いてある正式な手順(Ctrl + ドラッグ)は正直言ってわかりづらい。いつもどっちからドラッグするのかで迷ってしまう。それよりも、アウトレットを備えたオブジェクト上でポップアップメニューを出す方がずっとわかりやすい。マウスなら(特に設定を変えていない限り)右クリック、TrackPad なら 2 本の指でタップした状態でクリックでポップアップメニューが出てくる。メニューにあるアウトレットの右端の端子(○)を接続したいオブジェクトまでドラッグする。Ctrl キーを押す必要はない。

ドロワーの表示

ドロワーを表示するにはアプリコントローラからアウトレットを通して openOnEdge: メソッドを呼ぶ。このとき、親ウィンドウのどの端にドロワーを付けるかを引数として指定する。隠す際は close メソッドだ。

以下は、AppController.m からの抜粋だ。labelsDrawer は AppController クラスのアウトレットで、Interface Builder 上で Drawer オブジェクトに接続してある。

以下のコードでは、現在のドロワーの状態を取得し、それに応じて表示中なら close、非表示中なら openOnEdge: を呼んでいる。openOnEdge: にわたしている NSMinXEdge はウィンドウの左端を意味する定数だ。ドロワーを右端に表示したいなら NSMaxXEdge を指定する。

- (IBAction)toggleLabelsDrawer:(id)sender {
    NSDrawerState state = [labelsDrawer state];
    if (state == NSDrawerOpeningState || state == NSDrawerOpenState) {
        [labelsDrawer close];
        [showDrawerMenu setTitle:@"Show Labels"];
    } else {
        [labelsDrawer openOnEdge:NSMinXEdge];
        [showDrawerMenu setTitle:@"Hide Labels"];
    }
}

上記で、showDrawerMenu に対して setTitle: しているのは、ドロワーの状態によってドロワーを表示(または非表示)にするためのメニュー項目の文字列を変えるためだ。非表示状態では「Show Labels」に、表示中なら「Hide Labels」に置き換えている。showDrawerMenu も AppController のアウトレットで NSMenuItem * として宣言し、Interface Builder 上でメニュー項目と接続してある。

ラベル一覧の表示

前回(→「ラベル検索の実装 #1」)のラベル列挙と合わせると、ラベル一覧表示が可能になる。以下がそのスクリーンショットだ。

MacBloggerGlass プロトタイプ #0
ラベル一覧表示
ラベル一覧をドロワーとして実現した状態。一覧表示にふくまれているすべての記事に付いたラベルを集めてドロワー内のテーブルに表示している。

関連リンク

関連記事

0 件のコメント:

コメントを投稿