スライドビューの上手な作り方?

お試しで電子カタログを作ってみよ〜と思ったけど、ページの横スクロールさせるの、どーやるんだ?

お試し1:UINavigationController によるページ切り替え

最初に試したのは iPhone プログラミング UIKit 詳細リファレンス の 「3.2.3 たどった階層を一気にさかのぼる」方法。この方法は UINavigationController の階層を横っ飛びできる。なので、push と pop の関係を使うと前後に移動ができるって寸法。

例えば次のような感じのページ構成があるとする。

top (RootViewController)
  - page1 (PageViewController)
  - page2 (〃)
  - page3 (〃)

ソースコードだとこんな感じ。

switch (direction) {
    case PageImageViewSwipeDirectionRight: // 前ページへ
                ...
        rootCtrl = [self.navigationController.viewControllers objectAtIndex:0];
        prePageCtrl = [[PageViewController alloc] initWithPageIndex:pageIndex forBook:aPage.book];
        history = [NSArray arrayWithObjects:rootCtrl, prePageCtrl, self, nil];
        [self.navigationController setViewControllers:history animated:NO];
        [self.navigationController popViewControllerAnimated:YES]; // ★
        
        break;
    case PageImageViewSwipeDirectionLeft: // 次ページへ
                ...
        rootCtrl = [self.navigationController.viewControllers objectAtIndex:0];
        nextPageCtrl = [[PageViewController alloc] initWithPageIndex:pageIndex forBook:aPage.book];
        history = [NSArray arrayWithObjects:rootCtrl, nextPageCtrl, nil];
        [self.navigationController setViewControllers:history animated:YES]; // ★
        
        break;
    default:
                ...
        break;
}

この方法だと右にフリックするとビューが pop されるので左から新しいページが現れる。逆に左にフリックすると別ページに push された感じになるので、右から新しいページが現れる。フリック動作に連動した感じでよさそーだよね。:-)

でも、この方法だと右フリックしたときにナビゲーションバーの [Back] ボタンが消えちゃう現象が発生。タイミングの問題があるのかな? とうことで、ちょっとこの方法はあきらめモードになりました。(^^;)

お試し2: UIPageControl と UIScrollView によるページ切り替え

Apple サイトにいくと、いろいろなサンプルが公開されている。その1つに PageControl ってサンプルがあって、これを使うと、横スクロールを UIPageControl と UIScrolView で作ってる。

ビュー表示部は UIScrollView のフレームサイズを frame.size.width x ページ数だけ準備してそこに描画していくって寸法。各ページは独立した ViewController (= MyViewController) になってて、一度ビューの描画に使った ViewController はキャッシュしておいて、次回のアクセスでロード時間を短縮させるような仕組みになってる。

サンプルだとラベルを切り替え表示するだけなんだけど、画像をロードするように変更してみて実行すると、案の定、数ページ切り替えたくらいでアプリが落ちる。ViewController にひもづいて画像とか保持されるだろーし、UIScrollView の描画領域がとんでもなくでかくなるから、実用的ではない。そりゃ、そーだ。(^^;)

お試し3: Cocoaの日々さんの画面切り替え方式

どうせやるなら、iPhone の写真アプリみたく、さくさくページ切り替えしたい。

メモリ消費を抑えながらフリックでページを切り替えるなら、現在ページ(N)と一緒に前後ページ (N-1, N+1) をロードしておいて、N+1 方向に動いたら N+2 の画像をロードしつつ、N-1 ページを破棄するってのが良さそう。

なんか参考になるページとかないかな〜と思ってたら、Cocoa の日々さんの日記がすご〜い!!!電子カタログとか画像ビューア系で必要になりそうなノウハウがてんこもりじゃん。:-)


いろんなページにまたがってるから Cocoa の日記ページで簡易スライドビューア で検索するか、UIKit タグで絞り込み表示すると良いよ。:-)