14、无限轮播图
2017-01-20 本文已影响0人
深爱久随i
1.SDWebImage提供一个UIImageView的类别以支持加载来自网络的远程图片。具有缓存管理、异步下载、同一个URL下载次数控制和优化等特征
2.目前来说,主要用到了"UIImageView+WebCache.h",给出一个代码示例: 它是UIImageView的一个类目,在要使用它的类中加入#import"UIImageView+WebCache.h"调用 setImageWithURL:placeholderImage:方法。从异步下载到缓存管理,一切都会为你处理。
封装类的.m中
#import "TimerScroller.h"
#import "UIImageView+WebCache.h"
//判断外部传递进来的图片类型
typedef enum:NSUInteger{
ImageNamed=100,
ImageURL,
Image,
} SourceType;
@interface TimerScroller ()<UIScrollViewDelegate>
@property(nonatomic,retain)UIScrollView* myScrollerView;
@property(nonatomic,retain)UIImageView* leftImg;
@property(nonatomic,retain)UIImageView* centerImg;
@property(nonatomic,retain)UIImageView* rightImg;
@property(nonatomic,assign)int currentIndex;//记录当前显示的图片在数组中的位置
@property(nonatomic,retain)UIPageControl* myPageControl;
@property(nonatomic,retain)NSTimer* myTimer;
@property(nonatomic,assign)SourceType imageType;//图片类型
@end
@implementation TimerScroller
-(NSTimer*)myTimer{
if (!_myTimer) {
_myTimer=[NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(changeTimer) userInfo:nil repeats:YES];
[_myTimer setFireDate:[NSDate distantFuture]];
}
return _myTimer;
}
//定时器的回调方法
-(void)changeTimer{
//先改变偏移量 向右滚
[self.myScrollerView setContentOffset:CGPointMake(CGRectGetWidth(self.bounds)*2, 0) animated:YES];
//当前图片+1
self.currentIndex++;
//当currentIndex大于数组中的元素个数时,应该让显示第0张
if (self.currentIndex>=self.allImgsMArray.count) {
self.currentIndex=0;
}
self.myPageControl.currentPage=self.currentIndex;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self changeImageWithCurrentIndex:self.currentIndex];
});
}
-(UIPageControl*)myPageControl{
if (!_myPageControl) {
UIView* bgView=[[UIView alloc] initWithFrame:CGRectMake(0, CGRectGetHeight(self.bounds)-30, CGRectGetWidth(self.bounds), 30)];
_myPageControl=[[UIPageControl alloc] initWithFrame:CGRectMake(0, 0, CGRectGetWidth(self.bounds), 30)];
//设置视图的透明度,不会影响上面子视图的透明度
bgView.backgroundColor=[[UIColor blackColor] colorWithAlphaComponent:0.5];
// [_myPageControl addTarget:self action:@selector(pageAction:) forControlEvents:(UIControlEventValueChanged)];
[bgView addSubview:_myPageControl];
[self addSubview:bgView];
}
return _myPageControl;
}
//点击图片的回调方法
-(void)selectImg{
// NSLog(@"%d",self.currentIndex);
if (self.passBlock) {
self.passBlock(self.currentIndex);
}
}
-(UIScrollView*)myScrollerView{
if (!_myScrollerView) {
_myScrollerView=[[UIScrollView alloc] initWithFrame:self.bounds];
_myScrollerView.pagingEnabled=YES;
_myScrollerView.contentSize=CGSizeMake(CGRectGetWidth(self.bounds)*3, CGRectGetHeight(self.bounds));
_myScrollerView.directionalLockEnabled=NO;
//将显示的视图永远是第一屏 (0,1,2)
_myScrollerView.contentOffset=CGPointMake(CGRectGetWidth(self.bounds), 0);
_myScrollerView.delegate=self;
//添加手势
UITapGestureRecognizer* tap=[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(selectImg)];
[_myScrollerView addGestureRecognizer:tap];
[self addSubview:_myScrollerView];
}
return _myScrollerView;
}
-(UIImageView*)leftImg{
if (!_leftImg) {
_leftImg=[[UIImageView alloc] initWithFrame:CGRectMake(0, 0, CGRectGetWidth(self.bounds), CGRectGetHeight(self.bounds))];
[self.myScrollerView addSubview:_leftImg];
_leftImg.contentMode=UIViewContentModeScaleAspectFit;
}
return _leftImg;
}
-(UIImageView*)centerImg{
if (!_centerImg) {
_centerImg=[[UIImageView alloc] initWithFrame:CGRectMake(CGRectGetWidth(self.bounds), 0, CGRectGetWidth(self.bounds), CGRectGetHeight(self.bounds))];
[self.myScrollerView addSubview:_centerImg];
_centerImg.contentMode=UIViewContentModeScaleAspectFit;
}
return _centerImg;
}
-(UIImageView*)rightImg{
if (!_rightImg) {
_rightImg=[[UIImageView alloc] initWithFrame:CGRectMake(CGRectGetWidth(self.bounds)*2, 0,CGRectGetWidth(self.bounds), CGRectGetHeight(self.bounds))];
[self.myScrollerView addSubview:_rightImg];
_rightImg.contentMode=UIViewContentModeScaleAspectFit;
}
return _rightImg;
}
-(instancetype)initWithFrame:(CGRect)frame{
self=[super initWithFrame:frame];
if (self) {
//为三张图片赋值占位图片
self.leftImg.image=[UIImage imageNamed:@"01.jpg"];
self.centerImg.image=[UIImage imageNamed:@"02.jpg"];
self.rightImg.image=[UIImage imageNamed:@"03.jpeg"];
}
return self;
}
//重写数组的setter方法,当执行setter方法的时候,说明外部给数据了
-(void)setAllImgsMArray:(NSMutableArray *)allImgsMArray{
if (allImgsMArray&&allImgsMArray.count) {
//判断数据源的类型
id source=allImgsMArray.firstObject;
if ([source isKindOfClass:[UIImage class]]) {
//说明数组元素是图片类型,调用对应的初始化方法
self.imageType=Image;
[self sourceIsUIImageWithArray:allImgsMArray];
}else{
//说明为字符串
if ([source hasPrefix:@"http"]) {
self.imageType=ImageURL;
[self sourceIsImageURLWithArray:allImgsMArray];
}else{
self.imageType=ImageNamed;
[self sourceIsImageNamedWithArray:allImgsMArray];
}
}
}else{
NSLog(@"数据源不能为空");
return;
}
//当我们确定了数据的个数的时候,才可以确定小白点的个数
self.myPageControl.numberOfPages=allImgsMArray.count;
_allImgsMArray=allImgsMArray;
}
//当数据源为图片名称的时候
-(void)sourceIsImageNamedWithArray:(NSArray*)sourceArray{
if (sourceArray.count==1) {
//只有一张图片的时候,不能让scrollerView滚动
self.centerImg.image=[UIImage imageNamed:sourceArray.lastObject];
self.myScrollerView.pagingEnabled=NO;
}else if (sourceArray.count>=2){
//取出最后一个元素赋值给最左边的
NSString* last=sourceArray.lastObject;
self.leftImg.image=[UIImage imageNamed:last];
NSString* first=sourceArray[0];
self.centerImg.image=[UIImage imageNamed:first];
self.currentIndex=0;
NSString* next=sourceArray[1];
self.rightImg.image=[UIImage imageNamed:next];
[self.myTimer setFireDate:[NSDate distantPast]];
}
}
//当数据源为图片的URL的时候
-(void)sourceIsImageURLWithArray:(NSArray*)sourceArray{
if (sourceArray.count==1) {
//只有一张图片的时候,不能让scrollerView滚动
[self.centerImg sd_setImageWithURL:[NSURL URLWithString:sourceArray.lastObject] placeholderImage:[UIImage imageNamed:@"01.jpg"]];
self.myScrollerView.pagingEnabled=NO;
}else if (sourceArray.count>=2){
//取出最后一个元素赋值给最左边的
NSString* last=sourceArray.lastObject;
[self.leftImg sd_setImageWithURL:[NSURL URLWithString:last] placeholderImage:[UIImage imageNamed:@"02.jpg"]];
NSString* first=sourceArray[0];
[self.centerImg sd_setImageWithURL:[NSURL URLWithString:first] placeholderImage:[UIImage imageNamed:@"03.jpeg"]];
self.currentIndex=0;
NSString* next=sourceArray[1];
[self.rightImg sd_setImageWithURL:[NSURL URLWithString:next] placeholderImage:[UIImage imageNamed:@"03.jpeg"]];
[self.myTimer setFireDate:[NSDate distantPast]];
}
}
//当数据源为UIImage的时候
-(void)sourceIsUIImageWithArray:(NSArray*)sourceArray{
if (sourceArray.count==1) {
//只有一张图片的时候,不能让scrollerView滚动
self.centerImg.image=sourceArray.lastObject;
self.myScrollerView.pagingEnabled=NO;
}else if (sourceArray.count>=2){
//取出最后一个元素赋值给最左边的
self.leftImg.image=sourceArray.lastObject;
self.centerImg.image=sourceArray[0];
self.currentIndex=0;
self.rightImg.image=sourceArray[1];
[self.myTimer setFireDate:[NSDate distantPast]];
}
}
//停止减速的时候,画面静止会执行的代理方法
-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{
//先判断滑动方向
if (scrollView.contentOffset.x>=CGRectGetWidth(self.bounds)*2) {
//向右滑动,应该在当前显示的基础上+1
self.currentIndex++;
}else if (scrollView.contentOffset.x<=0){
//向左滑动,应该在当前显示的基础上-1
self.currentIndex--;
}
//说明当前显示的为最后一张,在+1就应该显示第0张
if (self.currentIndex==self.allImgsMArray.count) {
self.currentIndex=0;
}
//说明当前显示的为第0张,在-1,就应该显示最后一张
if (self.currentIndex<=-1) {
self.currentIndex=(int)self.allImgsMArray.count-1;
}
//当前显示第几张图片,小白点就处于对应的位置
self.myPageControl.currentPage=self.currentIndex;
//先将显示的图片进行更改
//将scrollerView的偏移量进行修改
[self changeImageWithCurrentIndex:self.currentIndex];
//当画面静止几秒
[self.myTimer setFireDate:[NSDate dateWithTimeIntervalSinceNow:5]];
}
//当用手拖拽的时候会执行的代理方法,(NSTimer不会执行该代理方法)
-(void)scrollViewWillBeginDragging:(UIScrollView *)scrollView{
//将定时器停止
[self.myTimer setFireDate:[NSDate distantFuture]];
}
//当滚动视图的时候,切换图片调用的方法.整个无限轮播图的算法核心
-(void)changeImageWithCurrentIndex:(int)index{
switch (self.imageType) {
case ImageNamed:
[self changeIamgeNamedWithCurrentIndex:index];
break;
case Image:
[self changeImageWithCurrentIndex:index];
break;
case ImageURL:
[self changeURLWithCurrentIndex:index];
break;
default:
break;
}
}
-(void)changeIamgeNamedWithCurrentIndex:(int)index{
//中间位置需要显示的图片名称
NSString* center=self.allImgsMArray[index];
self.centerImg.image=[UIImage imageNamed:center];
NSString* left;
NSString* right;
if (index==0) {
left=self.allImgsMArray.lastObject;
right=self.allImgsMArray[index+1];
}else if (index==self.allImgsMArray.count-1) {
right=self.allImgsMArray.firstObject;
left=self.allImgsMArray[index-1];
}else{
left=self.allImgsMArray[index-1];
right=self.allImgsMArray[index+1];
}
self.leftImg.image=[UIImage imageNamed:left];
self.rightImg.image=[UIImage imageNamed:right];
//将偏移量改回中间位置
[self.myScrollerView setContentOffset:CGPointMake(CGRectGetWidth(self.bounds), 0) animated:NO];
}
-(void)changeURLWithCurrentIndex:(int)index{
//中间位置需要显示的图片名称
NSString* center=self.allImgsMArray[index];
[self.centerImg sd_setImageWithURL:[NSURL URLWithString:center] placeholderImage:[UIImage imageNamed:@"01.jpg"]];
NSString* left;
NSString* right;
if (index==0) {
left=self.allImgsMArray.lastObject;
right=self.allImgsMArray[index+1];
}else if (index==self.allImgsMArray.count-1) {
right=self.allImgsMArray.firstObject;
left=self.allImgsMArray[index-1];
}else{
left=self.allImgsMArray[index-1];
right=self.allImgsMArray[index+1];
}
[self.leftImg sd_setImageWithURL:[NSURL URLWithString:left] placeholderImage:[UIImage imageNamed:@"01.jpg"]];
[self.rightImg sd_setImageWithURL:[NSURL URLWithString:right] placeholderImage:[UIImage imageNamed:@"01.jpg"]];
//将偏移量改回中间位置
[self.myScrollerView setContentOffset:CGPointMake(CGRectGetWidth(self.bounds), 0) animated:NO];
}
-(void)changeUIImageWithCurrentIndex:(int)index{
//中间位置需要显示的图片名称
// NSString* center=self.allImgsMArray[index];
self.centerImg.image=self.allImgsMArray[index];
UIImage* left;
UIImage* right;
if (index==0) {
left=self.allImgsMArray.lastObject;
right=self.allImgsMArray[index+1];
}else if (index==self.allImgsMArray.count-1) {
right=self.allImgsMArray.firstObject;
left=self.allImgsMArray[index-1];
}else{
left=self.allImgsMArray[index-1];
right=self.allImgsMArray[index+1];
}
self.leftImg.image=left;
self.rightImg.image=right;
//将偏移量改回中间位置
[self.myScrollerView setContentOffset:CGPointMake(CGRectGetWidth(self.bounds), 0) animated:NO];
}
@end
.h中
#import <UIKit/UIKit.h>
typedef void (^PassBlock)(int currentIndex);
@interface TimerScroller : UIView
@property(nonatomic,retain)NSMutableArray* allImgsMArray;//图片的集合
@property(nonatomic,copy)PassBlock passBlock;//当前位置
@end
运行结果如下
屏幕快照 2017-01-20 上午11.28.52.png