UIScrollView实现图片轮播有许多思路,当年刚做oc,找了许多demo学习,都不是太理想,一直想要一个高效精简的,后来偶然看到一位前辈的实现,觉得基本符合我的设想思路,于是整理使用至今。今天得空mark下,以备日后遗忘。
思路是只在UIScrollView上创建三个视图,通过轮播复用可以实现无限循环。
.h实现
@protocol JWHAdvertLoopViewDelegate;
@interface JWHAdvertLoopView : UIView
@property (nonatomic, assign) id delegate;
//当前页标记
@property (nonatomic, assign) NSInteger currentImageIndex;
//图像数组
@property (nonatomic, strong) NSMutableArray *imageAry;
/**
* 开启自动翻页
*
* @param shouldStart 开启自动翻页
*/
-(void)shouldAutoShow:(BOOL)shouldStart;
@end
@protocol JWHAdvertLoopViewDelegate
@optional
//点击回调代理方法
- (void)didClickPage:(JWHAdvertLoopView *)view atIndex:(NSInteger)index;
@end
两个属性,一个控制自动翻页的方法加一个点击代理,基本够用了。
.m实现
先加几个私有的属性 以及核心视图UIScrollView
@interface JWHAdvertLoopView ()
{
UIImageView *_leftView;
UIImageView *_middleView;
UIImageView *_rightView;
CGFloat _viewWidth;
CGFloat _viewHeight;
NSTimer *_autoScrollTimer;
UITapGestureRecognizer *_tap;
}
@property (nonatomic, readonly) UIScrollView *scrollView;
@end
@implementation JWHAdvertLoopView
- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
_viewWidth = self.bounds.size.width;
_viewHeight = self.bounds.size.height;
//设置scrollview
_scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, _viewWidth, _viewHeight)];
_scrollView.delegate = self;
_scrollView.contentSize = CGSizeMake(_viewWidth * 3, _viewHeight);
_scrollView.showsHorizontalScrollIndicator = NO;
_scrollView.pagingEnabled = YES;
_scrollView.delegate = self;
_scrollView.contentOffset = CGPointMake(_viewWidth, 0);
[self addSubview:_scrollView];
//设置三个view的frame,加到scrollview上
_leftView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, _viewWidth, _viewHeight)];
// _leftView.contentMode = UIViewContentModeScaleAspectFit;
[_scrollView addSubview:_leftView];
_middleView = [[UIImageView alloc] initWithFrame:CGRectMake(_viewWidth, 0, _viewWidth, _viewHeight)];
// _middleView.contentMode = UIViewContentModeScaleAspectFit;
[_scrollView addSubview:_middleView];
_rightView = [[UIImageView alloc] initWithFrame:CGRectMake(_viewWidth*2, 0, _viewWidth, _viewHeight)];
// _rightView.contentMode = UIViewContentModeScaleAspectFit;
[_scrollView addSubview:_rightView];
//设置单击手势
_tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(handleTap:)];
_tap.numberOfTapsRequired = 1;
_tap.numberOfTouchesRequired = 1;
[_scrollView addGestureRecognizer:_tap];
}
return self;
}
#pragma mark 单击手势
-(void)handleTap:(UITapGestureRecognizer*)sender {
if ([_delegate respondsToSelector:@selector(didClickPage:atIndex:)]) {
[_delegate didClickPage:self atIndex:_currentImageIndex];
}
}
#pragma mark 设置imageViewAry
-(void)setImageAry:(NSMutableArray *)imageAry {
if (imageAry) {
_imageAry = imageAry;
_currentImageIndex = 0; //默认为第0页
[self setInfoByCurrentImageIndex:_currentImageIndex];
}
}
- (void)setInfoByCurrentImageIndex:(NSUInteger)currentImageIndex {
_middleView.image = [_imageAry objectAtIndex:currentImageIndex];
_leftView.image = [_imageAry objectAtIndex:(currentImageIndex - 1 + _imageAry.count)%_imageAry.count];
_rightView.image = [_imageAry objectAtIndex:(currentImageIndex + 1)%_imageAry.count];
}
#pragma mark 刷新view页面
-(void)reloadData {
CGPoint contentOffset = [_scrollView contentOffset];
if (contentOffset.x > _viewWidth) { //向左滑动
_currentImageIndex = (_currentImageIndex + 1) % _imageAry.count;
} else if (contentOffset.x < _viewWidth) { //向右滑动
_currentImageIndex = (_currentImageIndex - 1 + _imageAry.count)%_imageAry.count;
}
[self setInfoByCurrentImageIndex:_currentImageIndex];
_scrollView.contentOffset = CGPointMake(_viewWidth, 0.0);
}
#pragma mark - UIScrollViewDelegate
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
if (self.imageAry.count == 1) {
_scrollView.contentSize = CGSizeMake(_viewWidth, _viewHeight);
return;
}
[self stopTimer];
[self reloadData];
[self startTimer];
}
#pragma mark 自动滚动
-(void)shouldAutoShow:(BOOL)shouldStart {
if (self.imageAry.count == 1) {
_scrollView.contentSize = CGSizeMake(_viewWidth, _viewHeight);
return;
}
if (shouldStart) { //开启自动翻页
[self startTimer];
}else { //关闭自动翻页
[self stopTimer];
}
}
- (void)startTimer {
if (!_autoScrollTimer) {
_autoScrollTimer = [NSTimer scheduledTimerWithTimeInterval:1.5f target:self selector:@selector(autoShowNextImage) userInfo:nil repeats:YES];
}
}
- (void)stopTimer {
if (_autoScrollTimer.isValid) {
[_autoScrollTimer invalidate];
_autoScrollTimer = nil;
}
}
#pragma mark 展示下一页
-(void)autoShowNextImage {
[_scrollView scrollRectToVisible:CGRectMake(_viewWidth * 2, 0, _viewWidth, _viewHeight) animated:YES];
[self reloadData];
}
- (void)dealloc {
[_autoScrollTimer invalidate];
_autoScrollTimer = nil;
_scrollView.delegate = nil;
}
@end