#importNS_ASSUME_NONNULL_BEGIN/** 点击block @param atIndex 点击的index */typedef void(^GLPageScrollViewDidSelectIndexBlock)(NSInteger atIndex);/** 滚动block @param toIndex 滚动到的位置 */typedef void(^GLPageScrollviewDidScrollToIndexBlock)(NSInteger toIndex);@interface ZTMineTopScollerView : UIView//装图片的数组 可以是图片也可以是地址@property (nonatomic,strong) NSArray *images;//轮播图定时@property (nonatomic,assign) NSTimeInterval timeinterval;@property (nonatomic,copy) GLPageScrollViewDidSelectIndexBlock didSelectIndexBlock;@property (nonatomic,copy) GLPageScrollviewDidScrollToIndexBlock didScrollToIndexBlock;/** * 启动定时器 */- (void)startTimer;/** * 暂停定时器 */- (void)pauseTimer;@endNS_ASSUME_NONNULL_END//// ViewController.m// 轮播图无限左划//// Created by asun on 2018/3/21.// Copyright © 2018年 asun. All rights reserved.//#import "ZTMineTopScollerView.h"//scrollView 的最大滚动范围static NSInteger const kMaxNumber = 3;//默认自动滚动时间//static CGFloat const kTimer = 2.0;@interface ZTMineTopScollerView () { //记录起始位置 CGFloat _startOffsetX; //记录将要滑动时的位置 CGFloat _willEndOffsetX; //记录滑动结束后的位置 CGFloat _endOffsetX;}//滚动view 用以承载view@property (nonatomic,strong) UIScrollView *scrollView;//最左侧@property (nonatomic,strong) UIImageView *leftImageView;//居中的@property (nonatomic,strong) UIImageView *middleImageView;//最右侧@property (nonatomic,strong) UIImageView *rightImageView;//当前显示的位置@property (nonatomic,assign) NSInteger currentIndex;//定时器@property (nonatomic, assign) CFRunLoopTimerRef timer;@end@implementation ZTMineTopScollerView- (id)initWithFrame:(CGRect)frame{ self = [super initWithFrame:frame]; if (self) { [self initialize]; } return self;}- (id)initWithCoder:(NSCoder *)aDecoder{ self = [super initWithCoder:aDecoder]; if (self) { [self initialize]; } return self;}- (id)init{ self = [super init]; if (self) { [self initialize]; } return self;}- (void)removeFromSuperview{ // [self pauseTimer]; [super removeFromSuperview];}#pragma mark == private method- (void)initialize{ self.backgroundColor = [UIColor blackColor]; self.currentIndex = 0; _startOffsetX = 0; _willEndOffsetX = 0; _endOffsetX = 0; // self.timeinterval = kTimer; [self addSubview:self.scrollView]; //添加手势 UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tap:)]; [self addGestureRecognizer:tap];}-(void)loadImage{ if (_endOffsetX < _willEndOffsetX && _willEndOffsetX < _startOffsetX) { //画面从右往左移动,前一页 _currentIndex = (_currentIndex + _images.count - 1) % _images.count; } else if (_endOffsetX > _willEndOffsetX && _willEndOffsetX > _startOffsetX) { //画面从左往右移动,后一页 _currentIndex = (_currentIndex + 1) % _images.count; } //左边的index NSInteger leftIndex = (_currentIndex + _images.count - 1) % _images.count; //右边的index NSInteger rightIndex = (_currentIndex + 1) % _images.count; // [_middleImageView setImageViewContent:_images[_currentIndex]]; // [_rightImageView setImageViewContent:_images[rightIndex]]; // [_leftImageView setImageViewContent: _images[leftIndex]]; [_middleImageView sd_setImageWithURL:[NSURL URLWithString:_images[_currentIndex]]]; [_rightImageView sd_setImageWithURL:[NSURL URLWithString:_images[rightIndex]]]; [_leftImageView sd_setImageWithURL:[NSURL URLWithString:_images[leftIndex]]];}- (void)startTimer{ [self cofigTimer];}//停止定时器- (void)pauseTimer{ if (self.timer) { CFRunLoopTimerInvalidate(self.timer); CFRunLoopRemoveTimer(CFRunLoopGetCurrent(), self.timer, kCFRunLoopCommonModes); }}//配置定时器- (void)cofigTimer{ if (self.images.count <= 1) { return; } if (self.timer) { CFRunLoopTimerInvalidate(self.timer); CFRunLoopRemoveTimer(CFRunLoopGetCurrent(), self.timer, kCFRunLoopCommonModes); } _timeinterval = 2; __weak typeof(self)weakSelf = self; CFRunLoopTimerRef time = CFRunLoopTimerCreateWithHandler(kCFAllocatorDefault, CFAbsoluteTimeGetCurrent()+ _timeinterval, _timeinterval, 0, 0, ^(CFRunLoopTimerRef timer) { [weakSelf autoScroll]; }); self.timer = time; CFRunLoopAddTimer(CFRunLoopGetCurrent(), time, kCFRunLoopCommonModes);}- (void)autoScroll{ //画面从左往右移动,后一页 _currentIndex = (_currentIndex + 1) % _images.count; //左边的index NSInteger leftIndex = (_currentIndex + _images.count - 1) % _images.count; //右边的index NSInteger rightIndex = (_currentIndex + 1) % _images.count; WS(weakSelf); [UIView animateWithDuration:0.8 animations:^{ [weakSelf.scrollView setContentOffset:CGPointMake(2 * weakSelf.scrollView.bounds.size.width, 0)]; } completion:^(BOOL finished) { [weakSelf.middleImageView sd_setImageWithURL:[NSURL URLWithString:weakSelf.images[_currentIndex]]]; [weakSelf.rightImageView sd_setImageWithURL:[NSURL URLWithString:weakSelf.images[rightIndex]]]; [weakSelf.leftImageView sd_setImageWithURL:[NSURL URLWithString:weakSelf.images[leftIndex]]]; [weakSelf.scrollView setContentOffset:CGPointMake(self.bounds.size.width, 0) animated:NO]; if (self.didScrollToIndexBlock) { self.didScrollToIndexBlock(weakSelf.currentIndex); } }];}#pragma mark == setter- (void)setImages:(NSMutableArray *)images{ if (!_images) { _images = [[NSMutableArray alloc] init]; } _images = images; if (images.count < 2){ if ([images[0] isKindOfClass:[UIImage class]]) { _scrollView.contentSize = CGSizeMake( self.bounds.size.width, self.bounds.size.height); [self.scrollView addSubview:self.leftImageView]; _leftImageView.image = images[0]; }else{ _scrollView.contentSize = CGSizeMake( self.bounds.size.width, self.bounds.size.height); [self.scrollView addSubview:self.leftImageView]; [_leftImageView sd_setImageWithURL:[NSURL URLWithString:_images[0]]]; } }else{ [self.scrollView addSubview:self.leftImageView]; [self.scrollView addSubview:self.middleImageView]; [self.scrollView addSubview:self.rightImageView]; [_leftImageView sd_setImageWithURL:[NSURL URLWithString:_images[images.count - 1]]]; [_middleImageView sd_setImageWithURL:[NSURL URLWithString:_images[_currentIndex]]]; [_rightImageView sd_setImageWithURL:[NSURL URLWithString:_images[_currentIndex + 1]]]; } [self startTimer];}#pragma mark == event response- (void)tap:(UITapGestureRecognizer *)tap{ if (self.didSelectIndexBlock) { self.didSelectIndexBlock(_currentIndex); }}#pragma mark == UIScrollViewDelegate//即将开始拖拽的时候- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView{ //拖动前的起始坐标 _startOffsetX = scrollView.contentOffset.x;}//停止拖拽的时候- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate{ [self startTimer];}//即将减速的时候- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset{ _willEndOffsetX = scrollView.contentOffset.x;}//减速停止的时候-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{ _endOffsetX = scrollView.contentOffset.x; //给imageview赋值 [self loadImage]; //改变offset [_scrollView setContentOffset:CGPointMake(self.bounds.size.width, 0) animated:NO]; if (self.didScrollToIndexBlock) { self.didScrollToIndexBlock(_currentIndex); }}//hwcf 4.11 hkyl 2层 600529 2层#pragma mark == 懒加载- (UIScrollView *)scrollView{ if (nil == _scrollView) { _scrollView = [[UIScrollView alloc] initWithFrame:self.bounds]; _scrollView.scrollEnabled = YES; _scrollView.pagingEnabled = YES; [_scrollView setContentOffset:CGPointMake(self.bounds.size.width, 0)]; _scrollView.contentSize = CGSizeMake(kMaxNumber * self.bounds.size.width, self.bounds.size.height); _scrollView.delegate = (id)self; _scrollView.showsVerticalScrollIndicator = _scrollView.showsHorizontalScrollIndicator = NO; } return _scrollView;}- (UIImageView *)leftImageView{ if (nil == _leftImageView) { _leftImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, CGRectGetWidth(self.scrollView.frame), CGRectGetHeight(self.scrollView.frame))]; _leftImageView.userInteractionEnabled = YES;// _leftImageView.contentMode = UIViewContentModeScaleAspectFit; UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleSingleTap:)]; [_leftImageView addGestureRecognizer:singleTap]; } return _leftImageView;}- (UIImageView *)middleImageView{ if (nil == _middleImageView) { _middleImageView = [[UIImageView alloc] initWithFrame:CGRectMake(CGRectGetWidth(self.scrollView.frame), 0, CGRectGetWidth(self.scrollView.frame), CGRectGetHeight(self.scrollView.frame))]; _middleImageView.userInteractionEnabled = YES;// _middleImageView.contentMode = UIViewContentModeScaleAspectFit; UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleSingleTap:)]; [_middleImageView addGestureRecognizer:singleTap]; } return _middleImageView;}- (UIImageView *)rightImageView{ if (nil == _rightImageView) { _rightImageView = [[UIImageView alloc] initWithFrame:CGRectMake(2 * CGRectGetWidth(self.scrollView.frame), 0, CGRectGetWidth(self.scrollView.frame), CGRectGetHeight(self.scrollView.frame))];// _rightImageView.contentMode = UIViewContentModeScaleAspectFit; _rightImageView.userInteractionEnabled = YES; UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleSingleTap:)]; [_rightImageView addGestureRecognizer:singleTap]; } return _rightImageView;}- (void)handleSingleTap:(UIGestureRecognizer *)gestureRecognizer {// self.hidden = YES; //do something....}@end