iOS-利用UIScrollView实现展示图片的无限滚动及自动滚动

时间:2021-10-09 20:40:22

  在很多应用中,都有利用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的时间不够准确。