在很多应用中,都有利用UIScrollView实现图片的无限滚动及自动滚动效果,下面我就跟大家分享下我是如何实现这种效果的。
1 // 2 // GXViewController.m 3 // 自动滚动及无线循环 4 // 5 // Created by 郭晓 on 14-3-7. 6 // Copyright (c) 2014年 郭晓. All rights reserved. 7 // 8 9 #import "GXViewController.h" 10 11 #define kCount 6 //图片总张数 12 13 static long step = 0; //记录时钟动画调用次数 14 15 @interface GXViewController () <UIScrollViewDelegate> 16 { 17 UIScrollView *_scrollView; 18 UIImageView *_currentImageView; //当前视图 19 UIImageView *_nextImageView; //下一个视图 20 UIImageView *_previousView; //上一个视图 21 CADisplayLink *_timer; //定时器 22 23 BOOL _isDraging; //当前是否正在拖拽 24 } 25 26 @end 27 28 @implementation GXViewController 29 30 - (void)viewDidLoad 31 { 32 [super viewDidLoad]; 33 34 CGFloat width = self.view.bounds.size.width; 35 CGFloat height = self.view.bounds.size.height; 36 37 _scrollView = [[UIScrollView alloc] initWithFrame:self.view.bounds]; 38 _scrollView.contentSize = CGSizeMake(3 * width, 0); 39 _scrollView.showsHorizontalScrollIndicator = NO; 40 _scrollView.pagingEnabled = YES; 41 _scrollView.delegate = self; 42 _scrollView.bounces = NO; 43 _scrollView.contentOffset = CGPointMake(width, 0); 44 [self.view addSubview:_scrollView]; 45 46 //初始化当前视图 47 _currentImageView = [[UIImageView alloc] init]; 48 _currentImageView.image = [UIImage imageNamed:@"01.jpg"]; 49 _currentImageView.frame = CGRectMake(width, 0, width, height); 50 _currentImageView.contentMode = UIViewContentModeScaleAspectFill; 51 [_scrollView addSubview:_currentImageView]; 52 53 //初始化下一个视图 54 _nextImageView = [[UIImageView alloc] init]; 55 _nextImageView.image = [UIImage imageNamed:@"02.jpg"]; 56 _nextImageView.frame = CGRectMake(width * 2, 0, width, height); 57 _nextImageView.contentMode = UIViewContentModeScaleAspectFill; 58 [_scrollView addSubview:_nextImageView]; 59 60 //初始化上一个视图 61 _previousView = [[UIImageView alloc] init]; 62 _previousView.image = [UIImage imageNamed:@"06.jpg"]; 63 _previousView.frame = CGRectMake(0, 0, width, height); 64 _previousView.contentMode = UIViewContentModeScaleAspectFill; 65 [_scrollView addSubview:_previousView]; 66 67 // 时钟动画 68 _timer = [CADisplayLink displayLinkWithTarget:self selector:@selector(update:)]; 69 [_timer addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode]; 70 71 } 72 73 #pragma mark 时钟动画调用方法 74 - (void)update:(CADisplayLink *)timer 75 { 76 step++; 77 78 if ((step % 120 != 0) || _isDraging) { 79 return; 80 } 81 82 CGPoint offset = _scrollView.contentOffset; 83 84 offset.x += 320; 85 if (offset.x > 640) { 86 offset.x = 320; 87 } 88 89 [_scrollView setContentOffset:offset animated:YES]; 90 } 91 92 #pragma mark - 代理方法 93 #pragma mark 准备开始拖动 94 - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView 95 { 96 _isDraging = YES; 97 } 98 99 #pragma mark 视图停止滚动 100 - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView 101 { 102 _isDraging = NO; 103 step = 0; 104 } 105 106 #pragma mark 已经拖动 107 - (void)scrollViewDidScroll:(UIScrollView *)scrollView{ 108 109 static int i = 1;//当前展示的是第几张图片 110 111 float offset = scrollView.contentOffset.x; 112 if (_nextImageView.image == nil || _previousView.image == nil) { 113 114 //加载下一个视图 115 NSString *imageName1 = [NSString stringWithFormat:@"0%d.jpg", i == kCount ? 1 : i + 1]; 116 _nextImageView.image = [UIImage imageNamed:imageName1]; 117 118 //加载上一个视图 119 NSString *imageName2 = [NSString stringWithFormat:@"0%d.jpg", i == 1 ? kCount : i - 1]; 120 _previousView.image = [UIImage imageNamed:imageName2]; 121 } 122 123 if (offset == 0) { 124 _currentImageView.image = _previousView.image; 125 scrollView.contentOffset = CGPointMake(scrollView.bounds.size.width, 0); 126 _previousView.image = nil; 127 128 if (i == 1) { 129 i = kCount; 130 }else{ 131 i -= 1; 132 } 133 134 } 135 136 if (offset == scrollView.bounds.size.width * 2) { 137 _currentImageView.image = _nextImageView.image; 138 scrollView.contentOffset = CGPointMake(scrollView.bounds.size.width, 0); 139 _nextImageView.image = nil; 140 141 if (i == kCount) { 142 i = 1; 143 }else{ 144 i += 1; 145 } 146 147 } 148 } 149 150 @end
注意:在代码中,使用到了6张用于展示的图片,图片名分别为01、02、03、04、05、06.
通过以上代码,就可以实现图片的无限滚动及自动滚动功能,之所以用CADisplayLink而不用NSTimer是因为NSTimer的时间不够准确。