NSPageController
でページのループを実装する方法を考えました。
NSPageControllerとは
スワイプによるビュー間の移動を可能にするCocoa用のクラスです。Xcodeのエディターエリアや、App Store、Spacesのページ移動には、多分これが使われています。
どんな風に実装するのか
ページの先頭と末尾に、末尾と先頭のページをそれぞれ挿入します。
実行時は、これら挿入したページに移動した時に、そのページのコピー元のページに移動するようにします。
例えばA、B、Cという3枚のページがあるとすると、こんな感じになります。
後述の具体例ではこの図と正確には異なりますが、概念的にはこんな感じです。
具体例
Appleが公開しているNSPageController
のサンプル「PictureSwiper」をいじって実装してみます。PictureSwiperは、複数枚の写真をスワイプによるページ移動で閲覧できる、簡易画像ビューアです。このサンプルに、ループを実装してみます。
今回変更するのはAppDelegate.m
だけです。
まず、AppDelegate
のapplicationDidFinishLaunching:
メソッドへ、下記のようにコード①、②を追加します。
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
/*
中略(画像ファイルを読み込み、self.dataにそのデータを詰め込む)
*/
// ①画像データの先頭と末尾に、末尾と先頭の画像データをそれぞれ挿入する
id firstData = self.data[0];
id lastData = self.data[self.data.count - 1];
[self.data addObject:firstData];
[self.data insertObject:lastData atIndex:0];
// set the first image in our list to the main magnifying view
if ([self.data count] > 0) {
[self.pageController setArrangedObjects:self.data];
}
// ②0ページ目には末尾のページを挿入したので、1ページ目を表示する
// (selectedIndex: 現在表示中のページのページ番号)
self.pageController.selectedIndex = 1;
}
次に、AppDelegate(NSPageControllerDelegate)
へ、下記メソッドを追加します。
// ページ移動時にこのメソッドが実行される
- (void)pageController:(NSPageController *)pageController didTransitionToObject:(id)object {
// 先頭のページに行けば最後から1つ手前のページへ、
// 最後のページに行けば先頭から1つ手前のページへ、
// それぞれ移動する
if (pageController.selectedIndex == 0) {
pageController.selectedIndex = pageController.arrangedObjects.count - 2;
}
else if (pageController.selectedIndex == pageController.arrangedObjects.count - 1) {
pageController.selectedIndex = 1;
}
}