UIScrollView 實現圖片自動輪轉

#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
相關文章
相關標籤/搜索