UIScrollview实现左右循环滑动和自动轮播

这个Demo的最初的想法是我从网上的一个简单的例子中获取的,加以修改,成了现在的样子。

我们在很多时候需要一个轮播图,比如项目中广告的轮播。能让scrollview自动滚动,这不是什么困难的事,但是如果能让scrollview朝一个方法循环播放下去,这费了我不少功夫。另外,这个demo中轮播的图片是5张,而scrollview的大小只能放下三张图片,所以这是一个少scrollview版的轮播图。为什么要这么做呢,并非自找麻烦,而是有些时候如果需要播放的图片特别多,比如1000张,那我们也要把scrollview的contentSize设为1000张图片的宽度吗?没有必要。除此之外,我还在demo中将自动轮播和手动滑动结合起来,使轮播图在自动轮播的同时,还可以响应用户交互。

如果代码有需要改进或者不对的地方,还望大家不吝赐教,谢谢!

#import "RandPicViewController.h"
#import "UIImageView+AFNetworking.h"

@interface RandPicViewController ()
{
    NSTimer * _timer;
    UIScrollView * _randPicScroll;
    UIPageControl * _pageControl;
    NSInteger _currentPage;
    NSMutableArray * _showImageviewArray;
}
@end

@implementation RandPicViewController

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor whiteColor];
    // Do any additional setup after loading the view.
    _showImageviewArray = [[NSMutableArray alloc] initWithCapacity:5];
    [self addRandPicScroll];
    
}
- (void)addRandPicScroll
{
    _randPicScroll = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 100, 320, 300)];
    _randPicScroll.backgroundColor = [UIColor whiteColor];
    _randPicScroll.contentSize = CGSizeMake(320*3, 300);
    _randPicScroll.pagingEnabled = YES;
    
    _currentPage = 1;
    [self.view addSubview:_randPicScroll];
    [self addImage];
    [self addPageControl];
}
- (void)addPageControl
{
    _pageControl = [[UIPageControl alloc] initWithFrame:CGRectMake(35, 380, 250, 20)];;
    _pageControl.numberOfPages = 5;
    _pageControl.currentPage = 0;
    [self.view addSubview:_pageControl];
    
    [self addTimer];
}
- (void)addImage
{
    //五张图片的URL
    NSMutableArray * UrlArray = [[NSMutableArray alloc] initWithObjects:@"http://d.hiphotos.baidu.com/ting/pic/item/342ac65c1038534395de43659013b07eca808865.jpg",@"http://b.hiphotos.baidu.com/ting/pic/item/9213b07eca8065388833704c94dda144ac348290.jpg",@"http://d.hiphotos.baidu.com/ting/pic/item/30adcbef76094b36e52e07b2a0cc7cd98d109d34.jpg",@"http://b.hiphotos.baidu.com/ting/pic/item/14ce36d3d539b600c81f5cedea50352ac75cb793.jpg",@"http://b.hiphotos.baidu.com/ting/pic/item/a50f4bfbfbedab64f92080b9f536afc379311e7d.jpg", nil];
    
    // 创建了5个imageview装入showImageviewArray中,在展示图片时取出其中三个。也可以将图片地址存入数组,取出三张图片之后,再创建UIImageview。
    
    for(int i = 0;i < 5;i++){
        UIImageView * imageView = [[UIImageView alloc] initWithFrame:CGRectMake(320*i, 0, 320, 300)];
        [imageView setImageWithURL:[NSURL URLWithString:UrlArray[i]]];
        [_showImageviewArray addObject:imageView];
    }
    
    [_randPicScroll addSubview:[_showImageviewArray objectAtIndex:0]];
    [_randPicScroll addSubview:[_showImageviewArray objectAtIndex:1]];
    [_randPicScroll addSubview:[_showImageviewArray objectAtIndex:2]];
    [_randPicScroll setContentOffset:CGPointMake(320, 0)];
    
    _randPicScroll.delegate = self;
}

//开始滑动scrollview触发此方法。

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
  //  当开始滑动scrollview时,关闭timer
    
    if(scrollView == _randPicScroll){
        [_timer invalidate];
    }
}

// scrollview滚动过程中触发此方法。

- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    //当scrollview滑动到第一张和最后一张时,都需要重新选取展示的三张图片
    
    if(scrollView == _randPicScroll){
        int x = _randPicScroll.contentOffset.x;
        if(x == 2* _randPicScroll.frame.size.width){
            
            //如果滑动至最后一张,则必定是从左到右滑动,将滑动之前的currentpage进行修改,重新选取当前添加在scrollview上的三张图。
            
            _currentPage = [self validateCurrentPage:_currentPage + 1];
            [self refreshScrollview];
        }else if (x == 0){
            
            //如果滑动至第一张,则必定是从右到左滑动,将滑动之前的currentpage修改,重新选取当前添加在scrollview上的三张图。
            
            _currentPage = [self validateCurrentPage:_currentPage - 1];
            [self refreshScrollview];
        }
    }
}

// 修改currentPage值。

- (NSInteger)validateCurrentPage:(NSInteger)value
{
    //滑动之后的图片如果超出了展示图片数组的右边界,则从第一张开始选取,若超出了左边界,即<0,则返回至最后一张选取。
    
    if(value == _showImageviewArray.count){
        value = 0;
    }else if (value == -1){
        value = _showImageviewArray.count - 1;
    }
    return value;
}

//currentpage修改之后,重新获取三组图片,并修改scrollview的contentOffSet。

- (void)refreshScrollview
{
    //移除当前scrollview上面的imageview
    
    NSArray * subviews = _randPicScroll.subviews;
    if(subviews.count != 0){
        [subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
    }
    
    //移除之后根据当前的currentpage重新选取一组imageview添加到scrollview上。
    
    UIImageView * currentImageview = [_showImageviewArray objectAtIndex:_currentPage];
    UIImageView * preImageview = [_showImageviewArray objectAtIndex:[self validateCurrentPage:_currentPage - 1]];
    UIImageView * nextImageview = [_showImageviewArray objectAtIndex:[self validateCurrentPage:_currentPage + 1]];
    
    //调整imageview的frame,使其能正确地显示在scrollview上
    
    [preImageview setFrame:CGRectMake(0, 0, 320, 300)];
    [currentImageview setFrame:CGRectMake(320, 0, 320, 300)];
    [nextImageview setFrame:CGRectMake(320*2, 0, 320, 300)];
    
    //添加imageview到scrollview上
    
    [_randPicScroll addSubview:preImageview];
    [_randPicScroll addSubview:currentImageview];
    [_randPicScroll addSubview:nextImageview];
    
    [_randPicScroll setContentOffset:CGPointMake(320, 0)];
    
}

//scrollview滚动结束。

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
    //在滑动scrollview时触发此方法,将pagecontrol的currentPage和_currentPage对应起来。
    
    _pageControl.currentPage = [self validateCurrentPage:_currentPage - 1];
    
    //待滑动结束,开启计时器,scrollview自动滑动。
    
    if(scrollView == _randPicScroll){
        [self addTimer];
    }
}
- (void)addTimer
{
    //添加计时器,使scrollview能够自动滑动。
    
    _timer = [NSTimer scheduledTimerWithTimeInterval:2 target:self selector:@selector(nextImage) userInfo:nil repeats:YES];
    [[NSRunLoop currentRunLoop] addTimer:_timer forMode:NSRunLoopCommonModes];

}

//添加计时器使scrollview自动滚动。

- (void)nextImage
{
    //此方法会触发scrollviewDidScroll执行。
    
    [_randPicScroll setContentOffset:CGPointMake(320*2, 0) animated:YES];
    
    //在scrollviewDidScroll执行之前将pgaecontrol的currentPage与_currentPage对应起来。
    
    _pageControl.currentPage = [self validateCurrentPage:_currentPage];
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}




你可能感兴趣的:(UIScrollview实现左右循环滑动和自动轮播)