#import <UIKit/UIKit.h> NS_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; @end NS_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 ()<UIScrollViewDelegate> { //記錄起始位置 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