IOS-无限图片轮播器控件

一.简介

图片轮播器在App中是一个最常见的功能,一般放在首页的顶、中部。

图片轮播器最基本功能:①定时循环无限滚动;②拖拽滚动;③点击跳转功能。

二.实现思路

实现图片轮播器有很多种方法,本文将采用最简单易懂的实现方法:一个 UIScrollView + 多个 UIImageView 或 UIButton。

1.首先根据传入的数据进行配置,假设传入三张图片 [A,B,C],将数组配置为 [C,A,B,C,A],感觉上就首尾相连。

2.再根据配置好的数组创建 UIImageView或UIButton 添加到 UIScrollView 上。

3.加载 PageControl。

4.实现定时器自动滚动:设置UIScrollView的ContentOffset = 当前ContentOffset + 一个图片的宽度。

5.在 UIScrollViewDelegate 的 scrollViewDidScroll 中实现:每次滚动获取当前ContentOffset 和 最大ContentOffset 进行判断,当当前ContentOffset 为0时代表此时显示的图为[C,A,B,C,A],就将 UIScrollView的ContentOffset 设置为 [C,A,B,C,A],同样的,当当前ContentOffset 为 最大ContentOffset时代表此时显示的图为[C,A,B,C,A],就将 UIScrollView的ContentOffset 设置为 [CA,B,C,A],注意两个地方设置 ContentOffset 时不能使用动画效果animated,这样就能实现头尾的无缝替换,感觉上是无限循环。


附上全部代码,复制下来就可以使用。

#import <UIKit/UIKit.h>

@interface GearSetView : UIScrollView

@property (nonatomic, copy) NSMutableArray *imgArr;//接受数据接口

@end
#import "GearSetView.h"

#define Self_Height self.bounds.size.height
#define Self_Width self.bounds.size.width

#define STWhiteColor [UIColor colorWithRed:255/255.0f green:255/255.0f blue:255/255.0f alpha:0.7]


@interface GearSetView () <UIScrollViewDelegate>

@property(nonatomic, weak) NSTimer *timer;//定时滚动

@property(nonatomic, strong) UIPageControl *pageControl;//页数控制器

@property(nonatomic, strong) UIScrollView *scrollView;

@end

@implementation GearSetView

#pragma mark - 重写 initWithFrame 和 layoutSubviews 方法
-(instancetype)initWithFrame:(CGRect)frame {
    if (self = [super initWithFrame:frame]) {
        self.backgroundColor = [UIColor clearColor];
        [self initScrollViewBase];
    }
    return self;
}

-(void) layoutSubviews {
    [super layoutSubviews];
}

#pragma mark - ScrollView基本设置
-(void) initScrollViewBase {
    
    self.scrollView = [[UIScrollView alloc]initWithFrame:CGRectMake(0, 0, Self_Width, Self_Height)];
    
    self.scrollView.scrollEnabled = YES;
    self.scrollView.pagingEnabled = YES;
    self.scrollView.bounces = NO;
    
    self.scrollView.alwaysBounceHorizontal = YES;
    self.scrollView.alwaysBounceVertical = NO;
    self.scrollView.showsVerticalScrollIndicator = NO;
    self.scrollView.showsHorizontalScrollIndicator = NO;

    self.scrollView.delegate = self;
    
    [self addSubview:self.scrollView];
}

#pragma mark - 重写外部数据接口Set
-(void) setImgArr:(NSMutableArray *)imgArr {
    
    //数组:最后一张+传入数组+第一张,感觉是首尾相连。
    _imgArr = [NSMutableArray array];
    [_imgArr addObject:imgArr[imgArr.count-1]];
    [_imgArr addObjectsFromArray:imgArr];
    [_imgArr addObject:imgArr[0]];
    
    //获取数据后去设置轮播显示内容
    [self loadImageView];
    
    [self loadPageControl];
    
    [self openTimer];
}

#pragma mark - 加载控件
-(void) loadImageView {
    
    self.scrollView.contentSize = CGSizeMake(Self_Width*_imgArr.count, Self_Height);
    
    for (int i=0; i<_imgArr.count; i++) {
        //这里使用btn来显示,也可以用imgView,视情况而定
        UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
        btn.frame = CGRectMake(Self_Width*i, 0, Self_Width, Self_Height);
        [btn setImage:[UIImage imageNamed:_imgArr[i]] forState:UIControlStateNormal];
        [btn addTarget:self action:@selector(chickToWeb) forControlEvents:UIControlEventTouchUpInside];
        [self.scrollView addSubview:btn];
    }
    
    self.scrollView.contentOffset = CGPointMake(Self_Width, 0);
}

-(void) loadPageControl {
    
    self.pageControl = [[UIPageControl alloc]initWithFrame:CGRectMake(0, Self_Height-24, Self_Width, 24)];
    self.pageControl.numberOfPages = _imgArr.count-2;//真实数量,减去首尾两张
    self.pageControl.currentPage = 0;
    self.pageControl.pageIndicatorTintColor = STWhiteColor;
    self.pageControl.currentPageIndicatorTintColor = [UIColor redColor];
    
    [self addSubview:self.pageControl];
}

#pragma mark - 开关定时器
-(void) openTimer {
    self.timer = [NSTimer scheduledTimerWithTimeInterval:3 target:self selector:@selector(automaticRolling) userInfo:nil repeats:YES];
}

-(void) stopTimer {
    if (self.timer != nil) {
        [self.timer invalidate];
        self.timer = nil;
    }
}

#pragma mark - 点击跳转事件
-(void) chickToWeb {
    //TODO:点击事件
    NSLog(@"跳转!");
}

#pragma mark - 定时器自动滚动事件
-(void) automaticRolling {
    //下一个偏移量 = 当前偏移量 + 一个宽度
    CGFloat contentOffsetX = self.scrollView.contentOffset.x + Self_Width;
    [self.scrollView setContentOffset:CGPointMake(contentOffsetX, 0) animated:YES];
}

#pragma mark - UIScrollViewDelegate 代理
-(void) scrollViewDidScroll:(UIScrollView *)scrollView {
    
    CGFloat contentoffsetX = self.scrollView.contentOffset.x;//当前x偏移量
    
    CGFloat max = Self_Width * (self.imgArr.count-1);//最大偏移量,假设有五张图,那么最大偏移量就是五张图的X坐标
    
    //向左滚动,偏移量为0时,重新设置偏移量为倒数第二张
    if (contentoffsetX <= 0) {
        CGFloat willOffsetX = Self_Width * (self.imgArr.count-2);
        [self.scrollView setContentOffset:CGPointMake(willOffsetX, 0) animated:NO];
    }
    //向右滚动,偏移量为最大时,重新设置偏移量为顺数第二张
    else if (contentoffsetX >= max) {
        [self.scrollView setContentOffset:CGPointMake(Self_Width, 0) animated:NO];
    }
    
    //根据偏移量设置当前页数
    self.pageControl.currentPage = self.scrollView.contentOffset.x/Self_Width - 1;
}

-(void) scrollViewWillBeginDragging:(UIScrollView *)scrollView {
    //开始拖动停止定时器
    [self stopTimer];
}

-(void) scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate {
    //停止拖动 先关闭定时器再开启定时器
    [self stopTimer];
    [self openTimer];
}

-(void)dealloc {
    self.delegate=nil;
    
    [self stopTimer];
}


@end

猜你喜欢

转载自blog.csdn.net/qq_36557133/article/details/80960466