封装一个简单轮播图类
在开发过程中,经常会使用到轮播图进行图片展示。通常轮播图由 UIScrollView 和 UIPageControl 两个控件组合而成。我们要创建一个轮播图,需要使轮播图能够根据图片数量进行无限轮播,并且页面控制控件的圆点也必须与轮播图一致。
之前我所知道的方法是,已知图片数量count,创建ScrollView时,设置contentSize为count+1个ScrollView的宽度,轮播至首尾时,需要进行图片的交换,给人感觉是不间断的无限轮播。现在,我们使用contentSize为3个ScrollView宽度的UIScrollView视图就可以实现无限轮播。如图:
将img1向左滑动,图片会显示为img2,在完成位移后,将img2的图片再次移动到img1上,并且使ScrollView的contentOffSet重新设置为img1的位置,这样,img2的图片在img1的位置又可以左右滑动,从而实现了无限轮播。
我们将这个思路整理一下,封装成一个简单的轮播图类:
1 // KLoopImg.h 2 3 /* 4 * 三个页面以上的轮播图 5 */ 6 7 #import <UIKit/UIKit.h> 8 9 typedef NS_ENUM(NSInteger, EScrollDirection){ 10 kScrollLift, 11 kScrollRight, 12 kScrollJudge, 13 }; 14 15 @interface KLoopImg : UIView 16 { 17 @public 18 int count; 19 int count0; 20 int count1; 21 int count2; 22 } 23 @property(nonatomic,strong)UIScrollView *loopImg; 24 @property(nonatomic,strong)UIImageView *img0; 25 @property(nonatomic,strong)UIImageView *img1; 26 @property(nonatomic,strong)UIImageView *img2; 27 @property(nonatomic,strong)UIPageControl *page; 28 @property(nonatomic,strong)NSArray *imgArray; 29 @property(nonatomic,strong)NSArray *actArray; 30 31 - (instancetype)initWithFrame:(CGRect)frame imgArray:(NSArray*)array; 32 33 /** 34 * 自动轮播 35 * @param direction 方向 36 */ 37 - (void)autoLoop:(EScrollDirection)direction; 38 39 /** 40 * 拖动图片 41 * @param direction 方向 42 */ 43 - (void)dragLoop:(EScrollDirection)direction; 44 45 /** 46 * 页码控制设置 47 * @param height 高度 48 * @param black 设置块 49 */ 50 - (void)pageSettingWithHeight:(CGFloat)height block:(void(^)(UIPageControl* page))block; 51 52 /** 53 * 页码控制 54 */ 55 - (void)pageChange; 56 57 /** 58 * 获取事件数组 59 */ 60 - (id)getActArray; 61 @end
1 // KLoopImg.m 2 3 #import "KLoopImg.h" 4 5 @interface KLoopImg () 6 { 7 @private 8 CGFloat loopImgWidth; 9 CGFloat loopImgHeight; 10 } 11 @end 12 13 @implementation KLoopImg 14 15 - (instancetype)initWithFrame:(CGRect)frame imgArray:(NSArray*)array{ 16 self = [super initWithFrame:frame]; 17 if(self){ 18 self.imgArray = array; 19 count = (int)self.imgArray.count; 20 count0 = 0; 21 count1 = 1; 22 count2 = 2; 23 [self setupView]; 24 } 25 return self; 26 } 27 28 - (void)setupView{ 29 self.backgroundColor = [UIColor whiteColor]; 30 31 loopImgWidth = self.frame.size.width; 32 loopImgHeight = self.frame.size.height; 33 34 self.loopImg = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, loopImgWidth, loopImgHeight)]; 35 self.loopImg.contentSize = CGSizeMake(3 * loopImgWidth, loopImgHeight); 36 /* 属性 */ { 37 self.loopImg.contentOffset = CGPointMake(loopImgWidth, 0); 38 self.loopImg.showsHorizontalScrollIndicator = NO; 39 self.loopImg.showsVerticalScrollIndicator = NO; 40 self.loopImg.pagingEnabled = YES; 41 self.loopImg.bounces = NO; 42 } 43 44 self.img0 = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, loopImgWidth, loopImgHeight)]; 45 self.img1 = [[UIImageView alloc] initWithFrame:CGRectMake(loopImgWidth, 0, loopImgWidth, loopImgHeight)]; 46 self.img1.userInteractionEnabled = YES; 47 self.img2 = [[UIImageView alloc] initWithFrame:CGRectMake(2 * loopImgWidth, 0, loopImgWidth, loopImgHeight)]; 48 49 [self.loopImg addSubview:self.img0]; 50 [self.loopImg addSubview:self.img1]; 51 [self.loopImg addSubview:self.img2]; 52 [self addSubview:self.loopImg]; 53 54 self.img0.image = [UIImage imageNamed:_imgArray[count0]]; 55 self.img1.image = [UIImage imageNamed:_imgArray[count1]]; 56 self.img2.image = [UIImage imageNamed:_imgArray[count2]]; 57 58 self.page = [UIPageControl new]; 59 self.page.alpha = 0; 60 [self addSubview:self.page]; 61 62 } 63 64 #pragma mark - 自动轮播 65 - (void)autoLoop:(EScrollDirection)direction{ 66 [UIView animateWithDuration:0.2 animations:^{ 67 if(direction == kScrollLift){ 68 self.loopImg.contentOffset = CGPointMake(2 * loopImgWidth, 0); 69 }else if(direction == kScrollRight){ 70 self.loopImg.contentOffset = CGPointMake(0, 0); 71 } 72 }]; 73 74 [self dragLoop:direction]; 75 } 76 77 #pragma mark - 拖动图片 78 - (void)dragLoop:(EScrollDirection)direction{ 79 if(direction == kScrollJudge){ 80 if(self.loopImg.contentOffset.x == 0){ 81 [self scroll:kScrollRight]; 82 }else if(self.loopImg.contentOffset.x == 2 * loopImgWidth){ 83 [self scroll:kScrollLift]; 84 } 85 }else{ 86 [self scroll:direction]; 87 } 88 } 89 90 #pragma mark - 拖动方向 91 - (void)scroll:(EScrollDirection)direction{ 92 self.loopImg.contentOffset = CGPointMake(LOOPIMG_W, 0); 93 if(direction == kScrollLift){ 94 count0 = count1; 95 count1 = count2; 96 count2 = (count2 + 1 == self.imgArray.count) ? 0: count2 + 1; 97 }else if(direction == kScrollRight){ 98 count2 = count1; 99 count1 = count0; 100 count0 = (count0 == 0) ? count - 1: count0 - 1; 101 } 102 { 103 self.img0.image = [UIImage imageNamed:self.imgArray[count0]]; 104 self.img1.image = [UIImage imageNamed:self.imgArray[count1]]; 105 self.img2.image = [UIImage imageNamed:self.imgArray[count2]]; 106 } 107 108 self.page.currentPage = count1 == 0 ? count - 1 : count1 - 1; 109 } 110 111 #pragma mark - 页码控制器设置 112 - (void)pageSettingWithHeight:(CGFloat)height block:(void(^)(UIPageControl* page))block{ 113 self.page.alpha = 1; 114 self.page.frame = CGRectMake(0, loopImgHeight - height, loopImgWidth, height); 115 self.page.backgroundColor = [UIColor colorWithWhite:0.000 alpha:0.500]; 116 self.page.pageIndicatorTintColor = [UIColor colorWithWhite:1.000 alpha:0.500]; 117 self.page.currentPageIndicatorTintColor = [UIColor whiteColor]; 118 self.page.numberOfPages = count; 119 if(block != nil){ 120 block(self.page); 121 } 122 else {/* 安全判断 */} 123 } 124 125 #pragma mark - 页码控制 126 - (void)pageChange{ 127 count1 = (int)(self.page.currentPage == count - 1 ? 0 : self.page.currentPage + 1); 128 count0 = (count1 - 1 < 0) ? count - 1 : count1 - 1; 129 count2 = (count1 + 1 == count) ? 0 : count1 + 1; 130 { 131 self.img0.image = [UIImage imageNamed:self.imgArray[count0]]; 132 self.img1.image = [UIImage imageNamed:self.imgArray[count1]]; 133 self.img2.image = [UIImage imageNamed:self.imgArray[count2]]; 134 } 135 } 136 137 #pragma mark - 获取事件数组元素 138 - (id)getActArray{ 139 return self.actArray[count1]; 140 } 141 @end
完成封装之后,进行使用:
1 // TestViewController.m 2 3 #import "TestViewController.h" 4 #import "KLoopImg.h" 5 #define SC_WIDTH CGRectGetWidth([UIScreen mainScreen].bounds) 6 #define SC_HEIGHT CGRectGetHeight([UIScreen mainScreen].bounds) 7 8 @interface TestViewController ()<UIScrollViewDelegate> 9 @property(nonatomic,strong)NSTimer *timer; 10 @property(nonatomic,strong)KLoopImg *loopImg; 11 @end 12 13 @implementation TestViewController 14 15 - (void)viewDidLoad { 16 [super viewDidLoad]; 17 18 self.view.backgroundColor = [UIColor whiteColor]; 19 20 // 图片均来自网络 21 self.loopImg = [[KLoopImg alloc]initWithFrame:CGRectMake(0, 50, SC_WIDTH, SC_WIDTH/2.0) 22 imgArray:@[@"01.png", @"02.png", @"03.png", @"04.png", @"05.png", @"hh.png"]]; 23 self.loopImg.loopImg.delegate = self; 24 self.loopImg.actArray = @[@"传颂之物", @"野良神", @"Chobits", @"海贼王", @"言叶之庭", @"中科网"]; 25 [self.loopImg pageSettingWithHeight:30 block:^(UIPageControl *page) { 26 [page addTarget:self action:@selector(pageCtr) forControlEvents:UIControlEventValueChanged]; 27 }]; 28 [self.view addSubview:self.loopImg]; 29 30 self.timer = [NSTimer scheduledTimerWithTimeInterval:2 target:self selector:@selector(setupTimer) userInfo:nil repeats:YES]; 31 32 UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(action)]; 33 [self.loopImg.img1 addGestureRecognizer:tap]; 34 } 35 36 // 计时器方法 37 - (void)setupTimer{ 38 [self.loopImg autoLoop:kScrollJudge]; 39 } 40 41 // 页面控制方法 42 - (void)pageCtr{ 43 NSLog(@"%ld", self.loopImg.page.currentPage); 44 [self.loopImg pageChange]; 45 } 46 47 // 点击图片响应事件 48 - (void)action{ 49 NSLog(@"%@", [self.loopImg getActArray]); 50 } 51 52 // 即将拖动时,关闭计时器 53 - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView{ 54 [self.timer invalidate]; 55 } 56 57 // 完成拖动,开启计时器 58 - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{ 59 [self.loopImg dragLoop:kScrollJudge]; 60 61 self.timer = [NSTimer scheduledTimerWithTimeInterval:2 target:self selector:@selector(setupTimer) userInfo:nil repeats:YES]; 62 } 63 64 - (void)didReceiveMemoryWarning { 65 [super didReceiveMemoryWarning]; 66 // Dispose of any resources that can be recreated. 67 } 68 @end
实际效果:
当然,这个Demo我也上传到了GitHub上:
https://github.com/Kriskee/KLoopImg