UIScrollView的循环滚动+UIPageControll+NSTimer实现的自动循环滚动播放最终完善版

时间:2021-10-09 20:39:52


//项目源码 :http://download.csdn.net/detail/xiaopeng5130301994/9590075


//  ViewController.m

//  UIScrollView循环滚动

//

//  Created by xp on 16/7/29.

//  Copyright © 2016 xiaopeng. All rights reserved.

//


//项目源码 :http://download.csdn.net/detail/xiaopeng5130301994/9590075

#import "ViewController.h"


NSInteger totalImage = 6;

@interface ViewController (){

    

}


@property (nonatomic,strong,readwrite)UIScrollView *scrollView;

@property (nonatomic,strong,readwrite)UIPageControl *pageControll;

@property (nonatomic,strong,readwrite)NSMutableArray *imageNameList;

@property (nonatomic,assign,readwrite)NSInteger currentIndex;

//初始化三个UIImageView

@property (nonatomic,strong,readwrite)UIImageView *leftImageView;

@property (nonatomic,strong,readwrite)UIImageView *currentImageView;

@property (nonatomic,strong,readwrite)UIImageView *rightImageView;



@property (nonatomic,strong,readwrite)NSTimer *timer;



//@property (nonatomic,strong,readwrite)NSMutableArray *

//初始化数据源

-(void)initializeDataSource;

//初始化用户界面

-(void)initializeUserInterface;


//初始化图片数据

-(void)initImages;


//scrollViewDidScroll触发时,时刻更新UI,此函数是实现循环的关键

-(void)updateUI;



//Timer事件处理

-(void)processTimer;


@end


@implementation ViewController


- (void)viewDidLoad {

    [superviewDidLoad];

    // Do any additional setup after loading the view, typically from a nib.

    [self initializeDataSource];

    [self initializeUserInterface];


}


//初始化数据源

-(void)initializeDataSource{

    

    _currentIndex =0;

    

    _imageNameList = [[NSMutableArray alloc]init];

    

    //初始化图片

    for(NSInteger i=0;i<totalImage;i++){

        NSString *imageName = [NSString stringWithFormat:@"%ld.png",i];

        [_imageNameList addObject:imageName];

    }

}




//初始化用户界面

-(void)initializeUserInterface{

    [self.view setBackgroundColor:[UIColor whiteColor]];

    

    CGFloat VIEW_WIDTH =CGRectGetWidth(self.view.bounds);

    _scrollView = [[UIScrollView alloc]initWithFrame:CGRectMake(0,20, VIEW_WIDTH, 260)];

    [_scrollView setDelegate:self];

    [_scrollView setBounces:NO];

    [_scrollView setShowsHorizontalScrollIndicator:NO];

    [_scrollView setContentSize:CGSizeMake(VIEW_WIDTH*3,260)];

    [_scrollView setPagingEnabled:YES];

    [_scrollView setContentOffset:CGPointMake(VIEW_WIDTH,0)];

    [self.viewaddSubview:_scrollView];

    

    

    //初始化三个UIImageView,并固定他们位于_scrollView中的位置

    _leftImageView = [[UIImageView alloc]initWithFrame:CGRectMake(0,0, VIEW_WIDTH, 260)];

    //[_leftImageView setContentMode:UIViewContentModeScaleToFill];

    

    _currentImageView = [[UIImageView alloc]initWithFrame:CGRectMake(VIEW_WIDTH,0, VIEW_WIDTH, 260)];

    [_currentImageView setContentMode:UIViewContentModeScaleToFill];

    

    _rightImageView = [[UIImageView alloc]initWithFrame:CGRectMake(VIEW_WIDTH*2,0, VIEW_WIDTH, 260)];

    [_rightImageView setContentMode:UIViewContentModeScaleToFill];

    

    //UIImage的图像来初始化三个ImageView;

    [selfinitImages];

    


    [_scrollView addSubview:_leftImageView];

    [_scrollView addSubview:_currentImageView];

    [_scrollView addSubview:_rightImageView];

    

    

    //初始化_pageControll

    _pageControll = [[UIPageControl alloc]initWithFrame:CGRectMake(0,260, VIEW_WIDTH, 30)];

    [_pageControll setNumberOfPages:totalImage];

    [_pageControll setCurrentPage:_currentIndex];

    [_pageControll setEnabled:NO];

    [_pageControll setCurrentPageIndicatorTintColor:[UIColor blackColor]];

    [_pageControll setPageIndicatorTintColor:[UIColor grayColor]];

    

    [self.viewaddSubview:_pageControll];

    

    

    //实例化_timer;

    _timer = [NSTimer scheduledTimerWithTimeInterval:target:self selector:@selector(processTimer) userInfo:nil repeats:YES];


}





-(void)initImages{

    //根据当前的_currentIndex(当前需要显示的索引)来初始化三个ImageView对应的图片

    [_leftImageView setImage:[UIImage imageNamed:_imageNameList[(_currentIndex-1+totalImage)%totalImage]]];

    [_currentImageView setImage:[UIImage imageNamed:_imageNameList[_currentIndex]]];

    [_rightImageView setImage:[UIImage imageNamed:_imageNameList[(_currentIndex+1)%totalImage]]];

}





-(void)updateUI{//核心函数

    

    CGFloat VIEW_WIDTH =CGRectGetWidth(self.view.bounds);

    CGFloat Offset_x =_scrollView.contentOffset.x;

    //判断是否需要更新界面

    BOOL isUpdate =NO;

    

    

    if(Offset_x==2*VIEW_WIDTH){

        isUpdate = YES;

        _currentIndex = (_currentIndex+1)%totalImage;

    }

    else if(Offset_x==0){

        isUpdate = YES;

        _currentIndex = (_currentIndex-1+totalImage)%totalImage;

    }

    //仅仅前面的ifelse if便能够实现完整的循环滚动

    

    

    //后面这两个else if和最后的else实现的功能是:当你页面划过一半时,_pageControll的当前页就立马换到上一页或者下一页,就不需要等滑动完才看到_pageControll更新。

    else if (Offset_x<=0.5*VIEW_WIDTH){

        //_pageControll更新到上一页

        [_pageControll setCurrentPage:(_currentIndex-1+totalImage)%totalImage];

    }

    else if (Offset_x>=1.5*VIEW_WIDTH){

        //_pageControll更新到下一页

        [_pageControll setCurrentPage:(_currentIndex+1)%totalImage];

    }


    //页面滑动未达到一半时,需要将_pageControll设置为当前索引页。有人可能会觉得设置为当前页是一个多余的操作,因为他们会想,页面都没划过一半,说明_pageControll就没改变过,为什么还要设置为当前页呢。原因是:当一个人将页面划过一半后,并未松手,他又划回低于一半页面时松手。这时,上面的两个else if()当中的一个将会触发,从而引起_pageControll当前页发生改变,所以我们需要做一个[_pageControll setCurrentPage:_currentIndex]来恢复当前的_pageControll显示页,这样做就能防止页面划过一半后又划回的操作。

    

    //又介于以下两个操作执行代码均相同,并且恰好是所有剩余的情况,所以我将其合并在else中执行。

    //为了理解,我也将以下else if()代码贴出并注释掉

    

    /*

    else if (Offset_x>0.5*VIEW_WIDTH&&Offset_x<VIEW_WIDTH){

        [_pageControll setCurrentPage:_currentIndex];

    }

    else if (Offset_x>VIEW_WIDTH&&Offset_x<1.5*VIEW_WIDTH){

        [_pageControll setCurrentPage:_currentIndex];

    }

     */

    else{

        [_pageControll setCurrentPage:_currentIndex];

    }

    

    

    

    if(!isUpdate){

        return;

    }

    

    [self initImages];

    [_scrollView setContentOffset:CGPointMake(VIEW_WIDTH,0)];

    [_pageControll setCurrentPage:_currentIndex];

    

    

}


-(void)processTimer{

    [_scrollView setContentOffset:CGPointMake(2*CGRectGetWidth(self.view.bounds),0)animated:YES];

    

}




//实现代理方法

-(void)scrollViewDidScroll:(UIScrollView *)scrollView{

    [self updateUI];

}


-(void)scrollViewWillBeginDragging:(UIScrollView *)scrollView{

    [_timer setFireDate:[NSDate distantFuture]];

}



-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{

    [_timer setFireDate:[NSDate dateWithTimeIntervalSinceNow:2]];

}




@end