CycleScrollView实现轮播图

//

//  CycleScrollView.h

//  PagedScrollView

//

//  Created by 李洪强 on 16-1-23.

//  Copyright (c) 2016年 李洪强. All rights reserved.

//

#import <UIKit/UIKit.h>

@interface CycleScrollView : UIView

@property (nonatomic , strong) NSTimer *animationTimer;

@property (nonatomic , readonly) UIScrollView *scrollView;

/**

 *  初始化

 *

 *  @param frame             frame

 *  @param animationDuration 自动滚动的间隔时长。如果<=0,不自动滚动。

 *

 *  @return instance

 */

- (id)initWithFrame:(CGRect)frame animationDuration:(NSTimeInterval)animationDuration;

- (void)pause;

- (void)restart;

/**

 数据源:获取总的page个数

 **/

@property (nonatomic ,copy) NSInteger (^totalPagesCount)(void);

/**

 数据源:获取第pageIndex个位置的contentView

 **/

@property (nonatomic , copy) UIView *(^fetchContentViewAtIndex)(NSInteger pageIndex);

/**

 当点击的时候,执行的block

 **/

@property (nonatomic , copy) void (^TapActionBlock)(NSInteger pageIndex);

@end



-------------------------------------------------------------------

//

//  CycleScrollView.m

//  PagedScrollView

//

//  Created by 李洪强 on 16-1-23.

//  Copyright (c) 2014年 李洪强. All rights reserved.

//

#import "CycleScrollView.h"

#import "NSTimer+Addition.h"

@interface CycleScrollView () <UIScrollViewDelegate>

{

    BOOL onlyOnePage;

}

@property (nonatomic , assign) NSInteger currentPageIndex;

@property (nonatomic , assign) NSInteger totalPageCount;

@property (nonatomic , strong) NSMutableArray *contentViews;

@property (nonatomic , strong) UIScrollView *scrollView;

@property (nonatomic , assign) NSTimeInterval animationDuration;

@property (nonatomic,strong) UIPageControl *pageControl;

@end

@implementation CycleScrollView

- (void)dealloc{

    [self.animationTimer invalidate];

    self.animationTimer = nil;

}

- (void)setTotalPagesCount:(NSInteger (^)(void))totalPagesCount{

    _totalPageCount = totalPagesCount();

    _pageControl.numberOfPages  = _totalPageCount;

    if (_totalPageCount > 0) {

        if (_totalPageCount > 1) {

            [self startTimerWithRepeats:YES];

        }

        else{

            self.animationDuration = 0.01;

            onlyOnePage = YES;

            [self startTimerWithRepeats:NO];

        }

    }

}

- (void)startTimerWithRepeats:(BOOL)repeats{

    if (!self.animationTimer){

        self.animationTimer = [NSTimer scheduledTimerWithTimeInterval:self.animationDuration

                                                               target:self

                                                             selector:@selector(animationTimerDidFired:)

                                                             userInfo:nil

                                                              repeats:repeats];

    }

    [self.animationTimer pauseTimer];

    CGPoint newOffset = CGPointMake(self.scrollView.contentOffset.x + CGRectGetWidth(self.scrollView.frame), self.scrollView.contentOffset.y);

    [self.scrollView setContentOffset:newOffset animated:repeats];

    [self configContentViews];

    [self.animationTimer resumeTimerAfterTimeInterval:self.animationDuration];

}

- (id)initWithFrame:(CGRect)frame animationDuration:(NSTimeInterval)animationDuration{

    self = [self initWithFrame:frame];

    if (animationDuration > 0.0) {

        self.animationDuration = animationDuration;

    }

    return self;

}

- (id)initWithFrame:(CGRect)frame{

    self = [super initWithFrame:frame];

    if (self) {

        // Initialization code

        self.autoresizesSubviews = YES;

        self.scrollView = [[UIScrollView alloc] initWithFrame:self.frame];

        self.scrollView.showsHorizontalScrollIndicator = NO;

        self.scrollView.autoresizingMask = 0xFF;

        self.scrollView.contentMode = UIViewContentModeCenter;

        self.scrollView.contentSize = CGSizeMake(3 * CGRectGetWidth(self.frame), 0);//.scrollView.frame

        self.scrollView.delegate = self;

        self.scrollView.contentOffset = CGPointMake(CGRectGetWidth(self.frame), 0);//self.scrollView.frame

        self.scrollView.pagingEnabled = YES;

        [self addSubview:self.scrollView];

        _scrollView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;

        self.currentPageIndex = 0;

        _pageControl = [[UIPageControl alloc]initWithFrame:CGRectMake(0, frame.size.height - 20, 100, 20)];

        CGFloat centerY = _pageControl.center.y;

        _pageControl.center = CGPointMake(self.width/2,centerY);

        [self addSubview:_pageControl];

    }

    return self;

}

#pragma mark -

#pragma mark - 私有函数

- (void)configContentViews{

    [self.scrollView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];

    [self setScrollViewContentDataSource];

    

    NSInteger counter = 0;

    for (UIView *contentView in self.contentViews) {

        contentView.userInteractionEnabled = YES;

        UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(contentViewTapAction:)];

        [contentView addGestureRecognizer:tapGesture];

        CGRect rightRect = contentView.frame;

        rightRect.origin = CGPointMake((CGRectGetWidth(self.scrollView.frame)) * (counter++), 0);

        contentView.frame = rightRect;

        [self.scrollView addSubview:contentView];

    }

    [_scrollView setContentOffset:CGPointMake(_scrollView.frame.size.width, 0)];

    if (onlyOnePage) {

        [_scrollView setContentSize:CGSizeMake(_scrollView.size.width, _scrollView.size.height)];

    }

}

/**

 *  设置scrollView的content数据源,即contentViews

 */

- (void)setScrollViewContentDataSource{

    NSInteger previousPageIndex = [self getValidNextPageIndexWithPageIndex:self.currentPageIndex - 1];

    NSInteger rearPageIndex = [self getValidNextPageIndexWithPageIndex:self.currentPageIndex + 1];

    if (self.contentViews == nil) {

        self.contentViews = [@[] mutableCopy];

    }

    [self.contentViews removeAllObjects];

    if (self.fetchContentViewAtIndex) {

        [self.contentViews addObject:self.fetchContentViewAtIndex(previousPageIndex)];

        [self.contentViews addObject:self.fetchContentViewAtIndex(_currentPageIndex)];

        [self.contentViews addObject:self.fetchContentViewAtIndex(rearPageIndex)];

    }

}

- (NSInteger)getValidNextPageIndexWithPageIndex:(NSInteger)currentPageIndex;

{

    if(currentPageIndex == -1) {

        return self.totalPageCount - 1;

    } else if (currentPageIndex == self.totalPageCount) {

        return 0;

    } else {

        return currentPageIndex;

    }

}

#pragma mark -

#pragma mark - UIScrollViewDelegate

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView

{

    [self.animationTimer pauseTimer];

}

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate

{

    [self.animationTimer resumeTimerAfterTimeInterval:self.animationDuration];

}

- (void)scrollViewDidScroll:(UIScrollView *)scrollView

{

    int contentOffsetX = scrollView.contentOffset.x;

    if(contentOffsetX >= (2 * CGRectGetWidth(scrollView.frame))) {

        self.currentPageIndex = [self getValidNextPageIndexWithPageIndex:self.currentPageIndex + 1];

        self.pageControl.currentPage = self.currentPageIndex;

//        NSLog(@"next,当前页:%d",self.currentPageIndex);

        [self configContentViews];

    }

    if(contentOffsetX <= 0) {

        self.currentPageIndex = [self getValidNextPageIndexWithPageIndex:self.currentPageIndex - 1];

        self.pageControl.currentPage = self.currentPageIndex;

//        NSLog(@"previous,当前页:%d",self.currentPageIndex);

        [self configContentViews];

    }

}

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView

{

    [scrollView setContentOffset:CGPointMake(CGRectGetWidth(scrollView.frame), 0) animated:YES];

}

#pragma mark -

#pragma mark - 响应事件

- (void)animationTimerDidFired:(NSTimer *)timer

{

    

    CGPoint newOffset = CGPointMake(self.scrollView.contentOffset.x + CGRectGetWidth(self.scrollView.frame), self.scrollView.contentOffset.y);

    [self.scrollView setContentOffset:newOffset animated:YES];

    

}

- (void)contentViewTapAction:(UITapGestureRecognizer *)tap

{

    if (self.TapActionBlock) {

        self.TapActionBlock(self.currentPageIndex);

    }

}

#pragma mark - 暂停  开始

- (void)pause{

    [self.animationTimer pauseTimer];

}

- (void)restart{

    [self.animationTimer resumeTimer];

}

@end



原文地址:https://www.cnblogs.com/LiLihongqiang/p/5718268.html