使用:
//
// ViewController.m
// Lesson_CarouselFigureView
//
// Created by Floating_SH on 15/12/12.
// Copyright © 2015年 SH. All rights reserved.
//
#import "ViewController.h"
#import "SHCarouselFigureView.h"
@interface ViewController ()<SHCarouselFigureViewDelegate>
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSMutableArray *array = [[NSMutableArray alloc]initWithCapacity:9];
for(int i = 1; i < 10;i++){
UIImage *image = [UIImage imageNamed:[NSString stringWithFormat:@"%d.jpg",i]];
[array addObject:image];
}
SHCarouselFigureView *carouselView = [[SHCarouselFigureView alloc]initWithFrame:self.view.bounds];
carouselView.duration = 3;
carouselView.delegate = self;
carouselView.images = array;
[self.view addSubview:carouselView];
}
- (void)carouselFigureViewDidCarousel:(SHCarouselFigureView *)carouselFigureView withIndex:(NSUInteger)index{
NSLog(@"%lu",index);
}
----------------------------以上为使用该轮播图----------------------------------
//
// SHCarouselFigureView.h
// Lesson_CarouselFigureView
//
// Created by Floating_SH on 15/12/12.
// Copyright © 2015年 SH. All rights reserved.
//
#import <UIKit/UIKit.h>
@class SHCarouselFigureView;
@protocol SHCarouselFigureViewDelegate <NSObject>
/**
* 轮播图被点击时触发的代理方法
*
* @param carouselFigureView 轮播图本身
* @param index 传递给外界的下标
*/
- (void)carouselFigureViewDidCarousel:(SHCarouselFigureView *)carouselFigureView withIndex:(NSUInteger)index;
@end
@interface SHCarouselFigureView : UIView
/**
* 图片数组,外界赋值轮播图片的时候使用,或者获取轮播图片时使用
*/
@property (strong,nonatomic) NSArray *images;
/**
* 图片切换间隔
*/
@property (assign,nonatomic) NSTimeInterval duration;//default is2.0
/**
* 当前下标
*/
@property (assign,nonatomic) NSUInteger currentIndex;
/**
* 代理对象
*/
@property (weak,nonatomic) id<SHCarouselFigureViewDelegate> delegate;
@end
//
// SHCarouselFigureView.m
// Lesson_CarouselFigureView
//
// Created by Floating_SH on 15/12/12.
// Copyright © 2015年 SH. All rights reserved.
//
#import "SHCarouselFigureView.h"
@interface SHCarouselFigureView ()<UIScrollViewDelegate>
//轮播图的三个重要元素
@property (strong ,nonatomic) UIScrollView *scrollView;
@property (strong ,nonatomic) UIPageControl *pageControl;
/**
* 驱动轮播的Timer
*/
@property (strong ,nonatomic) NSTimer *timer;
@end
@implementation SHCarouselFigureView
//每个视图都有这个初始化方法
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
_duration = 2;
//在初始化的时候初始化timer,如果在外界给图片的时候在初始化timer会出错
_timer = [NSTimer new];
}
return self;
}
//NSTimeInterval -->double类型
- (void)setDuration:(NSTimeInterval)duration{
[self.timer invalidate];
self.timer = nil;
_duration = duration;
self.timer = [NSTimer scheduledTimerWithTimeInterval:_duration target:self selector:@selector(carouselAction:) userInfo:self repeats:YES];//userInfo可以传递(传递的是后面的参数)
}
//一旦外界赋值就会触发set方法
/**
* images的setter,当对图片数组赋值时触发
*
* @param images 图片数组
*/
- (void)setImages:(NSArray *)images{
//让Timer停止并且为空
[self.timer invalidate];
self.timer = nil;
if(_images != images){
_images = nil;
_images = images;
}
//在外界对图片数组进行赋值的时候,开始绘图
[self drawView];
//在外界对图片数组进行赋值的时候,启动Timer
self.timer = [NSTimer scheduledTimerWithTimeInterval:self.duration target:self selector:@selector(carouselAction:) userInfo:self repeats:YES];
}
//绘制视图的方法
- (void)drawView{
//完成添加就可以,其他的放在懒加载中
[self addSubview:self.scrollView];
[self addSubview:self.pageControl];
}
//当前视图宽度
#define kWidth self.bounds.size.width
//当前视图高度
#define kHeight self.bounds.size.height
//当前图片个数
#define kCount self.images.count
//懒加载ScrollView
- (UIScrollView *)scrollView{
if (nil == _scrollView) {
//frame用外界传来的frame
_scrollView = [[UIScrollView alloc]initWithFrame:self.bounds];
[_scrollView setBounces:NO];//设置反弹
[_scrollView setPagingEnabled:YES];//设置滚动
[_scrollView setShowsHorizontalScrollIndicator:NO];
[_scrollView setShowsVerticalScrollIndicator:NO];
[_scrollView setContentSize:CGSizeMake(kWidth * kCount, kHeight)];
[_scrollView setDelegate:self];
//添加图片视图
for (int i = 0; i < kCount; i ++) {
UIImageView *imgView = [[UIImageView alloc]initWithFrame:CGRectMake(i * kWidth, 0, kWidth, kHeight)];
imgView.image = self.images[i];
imgView.userInteractionEnabled = YES;
imgView.tag = 1000 + i;
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(handlTapActionInImageView:)];
[imgView addGestureRecognizer:tap];
[_scrollView addSubview:imgView];
}
}
return _scrollView;
}
//懒加载PageControl
#define kGap 10
#define kPageControlHeight 29
- (UIPageControl *)pageControl{
if (! _pageControl) {
_pageControl = [[UIPageControl alloc]initWithFrame:CGRectMake(0, 0, kWidth, kPageControlHeight)];
[_pageControl setCenter:CGPointMake(kWidth / 2, kHeight - kPageControlHeight / 2)];
[_pageControl setBackgroundColor:[UIColor whiteColor]];
[_pageControl setPageIndicatorTintColor:[UIColor lightGrayColor]];
[_pageControl setCurrentPageIndicatorTintColor:[UIColor redColor]];
[_pageControl setNumberOfPages:kCount];
[_pageControl setHidesForSinglePage:YES];//剩余一个隐藏
}
return _pageControl;
}
#pragma mark --- Timer 驱动轮播机制 ---
//timer的方法没有返回值
- (void)carouselAction:(id)sender{
//每次方法执行的时候,"当前页" + 1
self.currentIndex ++;
//越界判断
if(self.currentIndex == kCount){
self.currentIndex = 0;
}
//根据"当前页"这一属性来设置pageControl显示第几个圆点
self.pageControl.currentPage = self.currentIndex;
//根据"当前页"这一属性来设置ScrollView的偏移量
self.scrollView.contentOffset = CGPointMake(kWidth * self.currentIndex, 0);
}
#pragma mark --- UIScrollViewDelegate ---
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView{
//开始拖拽时,Timer驱动机制停止
[self.timer invalidate];
self.timer = nil;
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{
//根据视图偏移矫正当前下标
self.currentIndex = scrollView.contentOffset.x / kWidth;
//根据新的下标校正pageControl的currentPage
self.pageControl.currentPage = self.currentIndex;
//停止减速后启动Timer
self.timer = [NSTimer scheduledTimerWithTimeInterval:self.duration target:self selector:@selector(carouselAction:) userInfo:self repeats:YES];
}
#pragma mark -- Tap 手势 ---
- (void)handlTapActionInImageView:(UITapGestureRecognizer *)tap{
//通过获取imgView.image在数组的下标
// //获取所点击的视图
// UIImageView *imgView = (UIImageView *)tap.view;
// //获取对应下标
// NSUInteger index = [self.images indexOfObject:imgView.image];
//通过tag值获取对应下标
//获取所点击的视图
UIImageView *imgView = (UIImageView *)tap.view;
//获取对应下标
NSUInteger index = imgView.tag - 1000;
//当手势触发时,代理对象执行代理方法
//将当前视图和当前下标携带给外界
if(_delegate && [_delegate respondsToSelector:@selector(carouselFigureViewDidCarousel:withIndex:)]){
[_delegate carouselFigureViewDidCarousel:self withIndex:index];
//这里不能传self.currentIndex 因为有偏差
}
}
@end