iOS无限轮播封装

作者: kakukeme | 来源:发表于2016-09-07 18:04 被阅读1962次

    无限轮播封装(代码主要参考这里)
    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 <UIKit/UIKit.h>
    
    /**
     *  原理很简单,就是放上3个UIImageView, 默认显示的是中间的UIImageView,
     *  当用户滑到下一张图片的临界点时候,偷偷的切换回中间的UIImageView展示,但是UIImage却全部换掉了;
     *  也就是说用户永远看到的是中间的UIImageView,只是内容不同而已。
     *
     */
    
    @class BannerView;
    @protocol BannerViewDelegate <NSObject>
    
    - (void) carouselTouch:(BannerView*)carousel atIndex:(NSUInteger)index;
    
    @end
    
    @interface BannerView : UIView
    
    @property (nonatomic, copy) void(^bannerTouchBlock)(NSUInteger index);
    
    @property (nonatomic, weak) id<BannerViewDelegate> 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 <SDWebImage/UIImageView+WebCache.h>
    
    @interface BannerView () <UIScrollViewDelegate>
    
    @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无限轮播封装

        本文链接:https://www.haomeiwen.com/subject/qfojettx.html