iOS无限轮播封装

无限轮播封装(代码主要参考这里)
http://blog.cocoachina.com/article/34641

三张Imageview实现无限图片轮播
http://my.oschina.net/iOSliuhui/blog/497070

iOS无限轮播图片的实现-仅仅用了三个UIImageView实现多图的轮播效果
http://blog.csdn.net/techfu/article/details/49888999

iOS开发--轮播图(无限循环)新玩法--视差轮播--无限循环的新思路(两个UIImageView足矣)
http://blog.csdn.net/wswei99/article/details/50827632

iOS开发之只用一个方法实现图片的轮播
http://www.imooc.com/article/12806

使用三个UIImageView实现多图的轮播效果

原理很简单,就是放上3个UIImageView, 默认显示的是中间的UIImageView,
当用户滑到下一张图片的临界点时候,偷偷的切换回中间的UIImageView展示,但是UIImage却全部换掉了;也就是说用户永远看到的是中间的UIImageView,只是内容不同而已。

1、BannerView.h文件

#import 

/**
 *  原理很简单,就是放上3个UIImageView, 默认显示的是中间的UIImageView,
 *  当用户滑到下一张图片的临界点时候,偷偷的切换回中间的UIImageView展示,但是UIImage却全部换掉了;
 *  也就是说用户永远看到的是中间的UIImageView,只是内容不同而已。
 *
 */

@class BannerView;
@protocol BannerViewDelegate 

- (void) carouselTouch:(BannerView*)carousel atIndex:(NSUInteger)index;

@end

@interface BannerView : UIView

@property (nonatomic, copy) void(^bannerTouchBlock)(NSUInteger index);

@property (nonatomic, weak) id delegate;

- (instancetype)initWithFrame:(CGRect)frame;

/**
 *  轮播图url数组
 *
 */
- (void)setupWithArray:(NSArray *)array;

/**
 *  本地图片数组;
 */
- (void)setupWithLocalArray:(NSArray *)array;

/**
 *  类初始化方法;
 *
 */
+ (instancetype)initWithFrame:(CGRect)frame
                    withArray:(NSArray*)array
                     hasTimer:(BOOL)hastimer
                     interval:(NSUInteger)inter;

+ (instancetype)initWithFrame:(CGRect)frame
                     hasTimer:(BOOL)hastimer
                     interval:(NSUInteger)inter
                  placeHolder:(UIImage*)image;

@end

2、BannerView.m文件

#import "BannerView.h"

#import 

@interface BannerView () 

@property BOOL hasTimer;
@property (nonatomic, assign) NSUInteger interval;

@property (nonatomic, strong) UIImage *placeHolder;

@property (nonatomic, strong) NSArray * imageArray;

@property (nonatomic, strong) UIScrollView *wheelScrollView;        // scrollView
@property (nonatomic, strong) UIPageControl *wheelPageControl;      // pageControl

@property (nonatomic, strong) NSTimer *timer;
@property (nonatomic, assign) NSUInteger currentImageIndex;

@property (nonatomic, strong) UIImageView *image1;
@property (nonatomic, strong) UIImageView *image2;
@property (nonatomic, strong) UIImageView *image3;

@property (nonatomic, assign) NSUInteger imageNum;

@property (nonatomic, strong) UIImageView *mask;
@property (nonatomic, assign) BOOL isLocal;

@end

@implementation BannerView

#pragma mark - init
+ (instancetype)initWithFrame:(CGRect)frame
                    withArray:(NSArray*)array
                     hasTimer:(BOOL)hastimer
                     interval:(NSUInteger)inter
{
    BannerView * carousel = [[BannerView alloc] initWithFrame:frame];
    carousel.hasTimer = hastimer;
    carousel.interval = inter;
    
    [carousel setupWithArray:array];
    return carousel;
}

+ (instancetype)initWithFrame:(CGRect)frame
                     hasTimer:(BOOL)hastimer
                     interval:(NSUInteger)inter
                  placeHolder:(UIImage*)image
{
    BannerView * carousel = [[BannerView alloc] initWithFrame:frame];
    carousel.placeHolder = image;
    carousel.hasTimer = hastimer;
    carousel.interval = inter;
    carousel.mask.image = image;
    
    
    return carousel;
}

- (instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        self.mask = [[UIImageView alloc] initWithFrame:frame];
        [self addSubview:self.wheelScrollView];
        [self addSubview:self.wheelPageControl];
        [self addSubview:self.mask];
        self.wheelScrollView.scrollEnabled = NO;
    }
    return self;
}


- (void)setupWithArray:(NSArray *)array
{
    self.wheelScrollView.scrollEnabled = YES;
    self.mask.hidden = YES;
    self.imageArray = array;
    self.imageNum = self.imageArray.count;
    self.currentImageIndex = 0;
    
    if (self.imageNum == 1) {
        self.wheelPageControl.hidden = YES;
        self.wheelScrollView.scrollEnabled = NO;
    }
    
    [self setup];
}

- (void)setupWithLocalArray:(NSArray *)array
{
    self.isLocal = YES;
    self.wheelScrollView.scrollEnabled = YES;
    self.mask.hidden = YES;
    self.imageArray = array;
    self.imageNum = self.imageArray.count;
    self.currentImageIndex = 0;
    
    if (self.imageNum == 1) {
        self.wheelPageControl.hidden = YES;
        self.wheelScrollView.scrollEnabled = NO;
    }
    
    [self setup];
}

/**
 *  初始化,启动定时器;轮播图片
 */
- (void)setup
{
    // 设置PageControl中心点
    self.wheelPageControl.pageIndicatorTintColor = [UIColor whiteColor];
    self.wheelPageControl.currentPageIndicatorTintColor = [UIColor blackColor];
    CGPoint p = CGPointMake(self.frame.size.width * 0.5, 0.92 * self.frame.size.height);
    self.wheelPageControl.center = p;
    
    if (self.hasTimer) {
        [self setupTimer];
    }
    [self updateImage];
}

/**
 *  图片更新
 */
- (void)updateImage
{
    self.imageNum = (int)self.imageArray.count;
    self.wheelPageControl.numberOfPages = self.imageNum;
    
    [self updateScrollImage];
}



- (void)updateScrollImage
{
    int left;
    int right;
    
    // 计算页数
    int page = self.wheelScrollView.contentOffset.x / self.wheelScrollView.frame.size.width;
    if (page == 0)
    {
        // 计算当前图片索引
        self.currentImageIndex = (self.currentImageIndex + self.imageNum - 1) % self.imageNum;   // %限定当前索引不越界;
    }
    else if(page == 2)
    {
        // 计算当前图片索引
        self.currentImageIndex = (self.currentImageIndex + 1) % self.imageNum;
    }
    
    // 当前图片左右索引
    left = (int)(self.currentImageIndex + self.imageNum - 1) % self.imageNum;
    right = (int)(self.currentImageIndex + 1) % self.imageNum;
    
    // 更换UIImage
    if (self.isLocal)
    {
        self.image1.image = [UIImage imageNamed:self.imageArray[left]];
        self.image2.image = [UIImage imageNamed:self.imageArray[self.self.currentImageIndex]];
        self.image3.image = [UIImage imageNamed:self.imageArray[right]];
    }
    else
    {
        [self.image1 sd_setImageWithURL:[NSURL URLWithString:self.imageArray[left]]  placeholderImage:self.placeHolder];
        [self.image2 sd_setImageWithURL:[NSURL URLWithString:self.imageArray[self.currentImageIndex]] placeholderImage:self.placeHolder];
        [self.image3 sd_setImageWithURL:[NSURL URLWithString:self.imageArray[right]] placeholderImage:self.placeHolder];
    }
    
    self.wheelPageControl.currentPage = self.currentImageIndex;
    [self.wheelScrollView setContentOffset:CGPointMake(self.wheelScrollView.frame.size.width, 0) animated:NO];
}

#pragma mark - NSTimer
- (void)setupTimer
{
    if (self.interval == 0)
    {
        self.interval = 3;
    }
    
    self.timer = [NSTimer scheduledTimerWithTimeInterval:self.interval target:self selector:@selector(updateWheel) userInfo:nil repeats:YES];
    
    // 避免tableview滚动时,定时器停止;
    [[NSRunLoop mainRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes];
}

- (void)updateWheel
{
    CGPoint offset = self.wheelScrollView.contentOffset;
    offset.x += self.wheelScrollView.frame.size.width;
    [self.wheelScrollView setContentOffset:offset animated:YES];
}



- (void)destroy
{
    [self.timer invalidate];
}

#pragma mark - UIScrollView
- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView
{
    [self updateScrollImage];
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
    [self updateScrollImage];
}

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
    [self.timer invalidate];
}

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
    [self setupTimer];
}


- (void)touchAction
{
    if ([self.delegate respondsToSelector:@selector(carouselTouch:atIndex:)]) {
        [self.delegate carouselTouch:self atIndex:self.currentImageIndex];
    }
    
    // 使用block的回调
    if (self.bannerTouchBlock)
    {
        self.bannerTouchBlock(self.currentImageIndex);
    }
}

#pragma mark - Getter

- (UIScrollView *)wheelScrollView
{
    if (!_wheelScrollView)
    {
        _wheelScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
        _wheelScrollView.backgroundColor = [UIColor clearColor];
        _wheelScrollView.pagingEnabled = YES;
        _wheelScrollView.delegate = self;
        _wheelScrollView.showsHorizontalScrollIndicator = NO;
        _wheelScrollView.showsVerticalScrollIndicator = NO;
        
        // 添加点击事件
        UITapGestureRecognizer * tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(touchAction)];
        [_wheelScrollView addGestureRecognizer:tap];
        
        // 使用3个UIImageView,
        _image1 = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
        _image2 = [[UIImageView alloc] initWithFrame:CGRectMake(self.frame.size.width, 0, self.frame.size.width, self.frame.size.height)];
        _image3 = [[UIImageView alloc] initWithFrame:CGRectMake(2*self.frame.size.width, 0, self.frame.size.width, self.frame.size.height)];
        _image2.image = self.placeHolder;
        
        for (UIImageView * img in @[_image1,_image2,_image3]) {
            [_wheelScrollView addSubview:img];
        }
        
        [_wheelScrollView setContentOffset:CGPointMake(self.frame.size.width, 0) animated:NO];
        _wheelScrollView.scrollEnabled = YES;
        _wheelScrollView.contentSize = CGSizeMake(3*self.frame.size.width, self.frame.size.height);
    }
    return _wheelScrollView;
}

- (UIPageControl *)wheelPageControl
{
    if (!_wheelPageControl)
    {
        _wheelPageControl = [[UIPageControl alloc] init];
        [_wheelPageControl setBackgroundColor:[UIColor clearColor]];
        _wheelPageControl.currentPage = 0;
        _wheelPageControl.numberOfPages = self.imageNum;
    }
    
    return _wheelPageControl;
}


@end

你可能感兴趣的:(iOS无限轮播封装)