前回のアイディアを元にしてサンプルを作ってみた。
サンプル
こんな感じ。8枚の小さな画像を左右にスクロールして見ることができる。
右端(左端)には BLANK と書かれた画像が配置されていて、バウンススクロールさせた時にはそれが(チラッと)表示される。
ソースコードは GitHubからどうぞ。
CirculationScroll at 2010-08-17 from xcatsan's iOS-Sample-Code - GitHub
解説
いくつかポイントがあるが、まずは画像の切り替わり検出について。前回のアイディアで説明したように、左右外側の UIImageView の再配置のタイミングは画像1個分がスクロールしたところで、これを検出する必要がある。
(前回の図より)
これは UIScrollViewDelegate のメソッド scrollViewDidScroll: が使える。
- (void)scrollViewDidScroll:(UIScrollView *)scrollView { CGFloat position = scrollView.contentOffset.x / IMAGE_WIDTH; CGFloat delta = position - (CGFloat)leftImageIndex_; if (fabs(delta) >= 1.0f) { if (delta > 0) { [self scrollWithDirection:kScrollDirectionRight]; } else { [self scrollWithDirection:kScrollDirectionLeft]; } } }IMAGE_WIDTH は画像1個の横幅。あらかじめ前回の位置を leftImageIndex_ に保存しておき、そこからのズレが画像1個分( >1.0f)になったかどうかで、画像1個分のスクロールが発生したかどうかを検出する。検出した後、実際のスクロール処理( scrollWithDirection:)を行う。
スクロール処理はこんな感じ。まずヘッダファイル。
@interface CirculationScrollViewController : UIViewController{ UIScrollView* scrollView_; NSArray* viewList_; NSArray* imageList_; NSInteger leftImageIndex_; // index of imageList NSInteger leftViewIndex_; // index of viewList NSInteger rightViewIndex_; // index of viewList } @property (nonatomic, retain) IBOutlet UIScrollView* scrollView; @property (nonatomic, retain) NSArray* viewList; @property (nonatomic, retain) NSArray* imageList; @end
定義
#define IMAGE_WIDTH 80 #define IMAGE_HEIGHT 80 #define DISPLAY_IMAGE_NUM 4 #define MAX_IMAGE_NUM (DISPLAY_IMAGE_NUM+2)
スクロール処理の実装
- (void)scrollWithDirection:(ScrollDirection)scrollDirection { NSInteger incremental = 0; NSInteger viewIndex = 0; NSInteger imageIndex = 0; if (scrollDirection == kScrollDirectionLeft) { incremental = -1; viewIndex = rightViewIndex_; } else if (scrollDirection == kScrollDirectionRight) { incremental = 1; viewIndex = leftViewIndex_; } // change position UIImageView* view = [self.viewList objectAtIndex:viewIndex]; CGRect frame = view.frame; frame.origin.x += IMAGE_WIDTH * MAX_IMAGE_NUM * incremental; view.frame = frame; // change image NSInteger numberOfImages = [self.imageList count]; leftImageIndex_ = leftImageIndex_ + incremental; if (scrollDirection == kScrollDirectionLeft) { imageIndex = leftImageIndex_ -1; } else if (scrollDirection == kScrollDirectionRight) { imageIndex = leftImageIndex_ + DISPLAY_IMAGE_NUM; } if (0 <= imageIndex && imageIndex < numberOfImages) { view.image = [self.imageList objectAtIndex:imageIndex]; } else { view.image = [self blankImage]; } // adjust indicies leftViewIndex_ = [self addViewIndex:leftViewIndex_ incremental:incremental]; rightViewIndex_ = [self addViewIndex:rightViewIndex_ incremental:incremental]; }前回のアイディアに沿った処理を行っているだけ。
1. 左(右)の外側の UIImageView を再配置する
2. UIImageView に新しい画像を設定する
3. インデックスを更新する
各インデックスのイメージは次の通り。
- - - -
インデックスの更新処理がややこしくて少々手こずったがなんとかできた。次は循環スクロールに挑戦する(もともとこれがしたかった)。
Responses
Leave a Response