画面分割その2

第2回 MOSA自習室(http://mosa.connpass.com/event/36300/)の発表用資料です。

説明が足らない部分は当日補足します。

画面分割の種類

画面分割(Splitting a window)には2種類あります。

  1. 一つ目は、同一の書類の異なる部分を同時に見るための機能。プレインストールアプリではターミナルアプリのWindowが典型的な画面になります。
../../../_images/terminal_app.png
  1. 二つ目は、iTunesやFinderのサイドバー等のMaster Detail構造のアプリです。
../../../_images/finder_app.png

ここでは、1の物を作ってみる。なお、NSSpliterViewは、おそらく2の物を作るために設計されたようです。2の型の分割を行うには素直にコーディングを行えば問題ありません。

分割の追加&削除ボタンの作成

スクロールバーにあるボタンの作り方だが、以前の「 画面分割その1 」 でやったので説明はパス。

分割の追加の方法

分割自体は簡単です。NSSplitViewControllerの以下のメソッドを呼んでいるだけです。

- (void)insertSplitViewItem:(NSSplitViewItem *)splitViewItem atIndex:(NSInteger)index;

問題は以下の2点です。

  • 分割の追加後に分割されたviewが再レイアウトされて、分割線の位置がずれる。
  • 新規に分割後のスクロール位置が原点を指している。

分割線の追加後に分割位置がずれる問題は、理想的な分割位置を計算して、以下のメソッドで再設定することで回避しています。

- (void)setPosition:(CGFloat)position ofDividerAtIndex:(NSInteger)dividerIndex;

理想的な分割位置は、「分割ボタンを押したNSScrollViewを2分割する位置」を理想と考えて計算しています。 このようにすることで、ユーザーは「今このScrollViewが分割された」と認識しやすくなります。

同じく、スクロール位置の調整は、分割されたNSScrollViewのコンテンツが連続する位置に移動しています。

何もしないと、以下のようにスクロール位置が原点を示します。

../../../_images/split_scrollpoint_1.png

調整することで、以下のようにコンテンツが連続する位置に調整しています。

../../../_images/split_scrollpoint_2.png

これも、ユーザーが分割を認識しやすくするために行っています。

分割の削除の方法

分割の削除も簡単です。NSSplitViewControllerの以下のメソッドを呼んでいるだけです。

- (void)removeSplitViewItem:(NSSplitViewItem *)splitViewItem;

問題は以下の2点です。

  • 分割の削除後にNSSplitViewが再レイアウトされて、分割線の位置がずれる。
  • フォーカスがある(firstResponder)の分割部分が削除された場合に、フォーカスが未設定になる。

分割線がずれる問題は、分割の追加と同じ手法で解決しています。 ユーザーが分割したことを認識しやすいように、削除した分割部の1つ上の部分だけが広がったように見せています。

フォーカスの未設定への対処は、削除された分割部の1個上の分割部分へフォーカスを移動しています。

コードでは、[TVSSplitViewController makeFirstResponderAtIndex]を参照してください。

分割線の移動方法

NSSplitViewのサブクラスなので何もしないでも分割線( split bar )は移動できます。

が、デフォルトのままだと、分割線の移動時にコンテンツの中身と一緒に移動してしまいます。

これの何処が問題なのかは説明が難しいので、当日現場で説明します。

理想と現実

ここまで作ってみましたが、より良いユーザーインターフェイスとして以下のようなものがあります。

../../../_images/better_splitView.png

Inside Machintoshで紹介されている例です。 ターミナルアプリにあるような分割の追加&削除ボタンは存在しません。 スクロールバーに分轄用の黒い split bar が付いているだけです。 この split bar をドラッグすると、スクロールバー上を split bar が移動し、マウスを離すとその位置で新たに画面が分轄されます。 分轄部分を削除するには、 split bar をスクロールバーの端っこまで移動すると消えます。

この Inside Machintosh で紹介されている方式の方が、以下の2点で優れている。

  • 画面上のコントロールが少ない。「ボタン2個 + split bar1個」から「split bar1個」に減っている。
  • ユーザの作業が少ない。「分割後にsplit barの移動」から「split barの移動」だけに減っている。

この方式が劣っているのは、Appleの標準のアプリで採用している例が無いので、初見では操作方法が解りにくい事くらいと思われる。

あと、ソースコードはここ TableViewSpliter.zip に置いときます。

次回は、こちらの方式を実装してみたいです。じゃあね。