一.简介
图片轮播器在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 设置为 [C,A,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