画面分割その2
第2回 MOSA自習室(http://mosa.connpass.com/event/36300/)の発表用資料です。
説明が足らない部分は当日補足します。
画面分割の種類
画面分割(Splitting a window)には2種類あります。
- 一つ目は、同一の書類の異なる部分を同時に見るための機能。プレインストールアプリではターミナルアプリのWindowが典型的な画面になります。
- 二つ目は、iTunesやFinderのサイドバー等のMaster Detail構造のアプリです。
ここでは、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のコンテンツが連続する位置に移動しています。
何もしないと、以下のようにスクロール位置が原点を示します。
調整することで、以下のようにコンテンツが連続する位置に調整しています。
これも、ユーザーが分割を認識しやすくするために行っています。
分割の削除の方法
分割の削除も簡単です。NSSplitViewControllerの以下のメソッドを呼んでいるだけです。
- (void)removeSplitViewItem:(NSSplitViewItem *)splitViewItem;
問題は以下の2点です。
- 分割の削除後にNSSplitViewが再レイアウトされて、分割線の位置がずれる。
- フォーカスがある(firstResponder)の分割部分が削除された場合に、フォーカスが未設定になる。
分割線がずれる問題は、分割の追加と同じ手法で解決しています。 ユーザーが分割したことを認識しやすいように、削除した分割部の1つ上の部分だけが広がったように見せています。
フォーカスの未設定への対処は、削除された分割部の1個上の分割部分へフォーカスを移動しています。
コードでは、[TVSSplitViewController makeFirstResponderAtIndex]を参照してください。
分割線の移動方法
NSSplitViewのサブクラスなので何もしないでも分割線( split bar )は移動できます。
が、デフォルトのままだと、分割線の移動時にコンテンツの中身と一緒に移動してしまいます。
これの何処が問題なのかは説明が難しいので、当日現場で説明します。
理想と現実
ここまで作ってみましたが、より良いユーザーインターフェイスとして以下のようなものがあります。
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 に置いときます。
次回は、こちらの方式を実装してみたいです。じゃあね。