画像を横に並べたスクロールビューアの作成 [2] サンプル

2010年8月17日火曜日 | Published in | 0 コメント

このエントリーをはてなブックマークに追加

[前回] Cocoaの日々: 画像を横に並べたスクロールビューアの作成 [1] アイディア

前回のアイディアを元にしてサンプルを作ってみた。


サンプル

こんな感じ。


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

人気の投稿(過去 30日間)