前回からスライドショー(数秒単位で画像が切り替わる)の実装を始めたが、途中で止めたり、フリックした時の挙動がおかしかった。これを直していこう。
タッチで停止
標準の画像アプリのスライドショーのように画面をタッチしたら停止するようにする。
現在のビュー構成はこんな感じ。
タッチイベント(touchesBegan:withEvent:)は一番上の XCGalleryInnerScrollView が受け取るが、その下のビューへは自動的に伝搬されない。そこで自前のプロトコルを定義して、それを実装するデリゲートへイベントを転送してやる。
@class XCGalleryInnerScrollView; @protocol XCGalleryInnerScrollViewDelegate - (void)innerScrollView:(XCGalleryInnerScrollView*)innerScrollView touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event; @end @interface XCGalleryInnerScrollView : UIScrollView{ UIImageView* imageView_; id eventDelegate_; } @property (nonatomic, retain) UIImageView* imageView; @property (nonatomic, assign) id eventDelegate
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { [self.eventDelegate innerScrollView:self touchesBegan:touches withEvent:event]; }eventDelegate には XCGalleryView を指定しておき、このメッセージが投げられたらスライドショー実行(タイマー)を停止する。
- (void)innerScrollView:(XCGalleryInnerScrollView*)innerScrollView touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { NSLog(@"touchesBegan2"); [self stopSlideShow]; }
画像切替ロジックの変更
前回はベースとなる UIScrollView の位置を動かさず、表示中の XCGalleryInnerScrollView をその場でトランジションをかけて表示していた。この為、スライドショー実行を中断した後フリックしてページをめくると左右の画像がおかしなことになる。これを回避するためにスライドショー実行中はベースの UIScrollView をスクロールさせて正しい位置でトランジションをかける必要がある。
前回のトランジションイメージはこう。
これを次のように変える。ある時点で下記の状態になっていたとする。
タイマーが発火した時点で次の画像位置へベースの UIScrollViewをスクロールさせる(可視範囲が動く)。この直前に transitionView にひとつ前の画像を表示する(hidden=NO)。一方、本来表示されるべき n番目のビューは hidden=YESとして非表示にする。
最後に CATransitionを使い、表示・非表示をそれぞれのビューで逆転させる。
これでトランジションと共にスクロール位置も正しく設定されるので、スライドショーを停止してもその後の位置関係がおかしくならない。
ソースコード
GitHubからどうぞ。
EasyGallery at 2010-10-18 from xcatsan's iOS-Sample-Code - GitHub
Responses
Leave a Response