我们经常在一些app或者网页上上面看到一些轮播器,效果就是每一张图片显示一段时间之后一段时间过后就自动跳到下一张图片,并且有一个UIPageControl控件实现页面指示效果,并且是图片是循环不间断的,最近看到腾讯英雄联盟里面有一个轮播器,可是貌似有个bug,刚开始加载的时候轮播器好像不能往前拨,等到轮了一圈之后才能往前拨。现在分享一下我的代码。
#import "ViewController.h"
#import <UIKit/UIKit.h>
//定义有5张图片,这里可以自己找5张图片改一下名字img_0i(i 从1到5)
#define count 5
@interface ViewController () <UIScrollViewDelegate>
//界面共有两个控件,注意scrollView与pagecontrol处于同一容器同等关系
@property (weak, nonatomic) IBOutlet UIScrollView *scrollView;
@property (weak, nonatomic) IBOutlet UIPageControl *pageControl;
@property (nonatomic, strong)NSTimer *timer;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
//设置代理
self.scrollView.delegate = self;
//设置scrollView的内容尺寸
self.scrollView.contentSize = CGSizeMake(self.scrollView.bounds.size.width * (count+2), self.scrollView.bounds.size.height);
//设置每张图片的高度与宽度等于scrollView本身的frame框架
CGFloat imgW = self.scrollView.frame.size.width;
CGFloat imgH = self.scrollView.frame.size.height;
CGFloat imgY = 0;
//设置图片信息,共有5张图片,可是在第一张图片前面添加最后一张图片,在最后一张图片添加第一张图片,起到欺骗视觉作用
UIImageView *firstImg = [[UIImageView alloc] init];
firstImg.image = [UIImage imageNamed:@"img_05"];
firstImg.frame = CGRectMake(0, imgY, imgW, imgH);
[self.scrollView addSubview:firstImg];
UIImageView *lastImg = [[UIImageView alloc] init];
lastImg.image = [UIImage imageNamed:@"img_01"];
lastImg.frame = CGRectMake((count+1) * imgW, imgY, imgW, imgH);
[self.scrollView addSubview:lastImg];
for (int i = 0; i < count; i++) {
UIImageView *img = [[UIImageView alloc] init];
img.image = [UIImage imageNamed:[NSString stringWithFormat:@"img_%02d",i+1]];
img.frame = CGRectMake((i+1) * imgW, imgY, imgW, imgH);
[self.scrollView addSubview:img];
}
//初始化scrollView的偏移值,使其对准第一张图片的位置
self.scrollView.contentOffset = CGPointMake(imgW, imgY);
self.scrollView.pagingEnabled = YES;
self.scrollView.showsHorizontalScrollIndicator = NO;
self.pageControl.currentPage = 0;
//设置定时器,使其每一段时间执行下一页的功能
self.timer = [NSTimer timerWithTimeInterval:1.5 target:self selector:@selector(nextImg) userInfo:nil repeats:YES];
//把定时器加入runloop中,实现时间片轮转,不会因为拖动其他的空间而导致轮播器不播放
NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
[runLoop addTimer:self.timer forMode:NSRunLoopCommonModes];
}
//根据图片在scrollView中的偏移值改变scrollView的显示内容
-(void)nextImg{
CGFloat offsetX = self.scrollView.contentOffset.x;
int index = offsetX / self.scrollView.frame.size.width;
index ++;
[self.scrollView setContentOffset:CGPointMake(index * self.scrollView.frame.size.width, 0) animated:YES];
}
//代理方法,scrollView滚动的时候会自动执行这个方法
-(void)scrollViewDidScroll:(UIScrollView *)scrollView{
CGFloat width = self.scrollView.frame.size.width;
CGFloat offsetX = self.scrollView.contentOffset.x;
int index = (offsetX + width * 0.5) / width;
self.pageControl.currentPage = index - 1;
}
//scrollView被拖动的时候调用这个方法,关闭定时器,防止定时器在后台继续运行导致放手的时候图片加速跑
-(void)scrollViewWillBeginDragging:(UIScrollView *)scrollView{
[self.timer invalidate];
self.timer = nil;
}
//scrollView停止拖动的时候重新启动定时器并加入runloop中
-(void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate{
self.timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(nextImg) userInfo:nil repeats:YES];
NSRunLoop *runloop = [NSRunLoop mainRunLoop];
[runloop addTimer:self.timer forMode:NSRunLoopCommonModes];
}
//每当第一页向前翻到最后一页,或者最后一页向后放到第一页,在图片稳定下来的一瞬间,把图片的位置换到真实的位置,起到图片的轮播作用。(注:只用设置翻滚的时候为animation这个方法才会执行)
-(void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView{
CGFloat width = self.scrollView.frame.size.width;
CGFloat offsetX = self.scrollView.contentOffset.x;
int index = (offsetX + width * 0.5)/width;
if (index == count + 1) {
[self.scrollView setContentOffset:CGPointMake(width, 0) animated:NO];
}else if(index == 0){
[self.scrollView setContentOffset:CGPointMake(count * width, 0) animated:NO];
}
}
//scrollView滚动降速的时候调用(注:只用设置翻滚的时候为animation这个方法才会执行)
-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{
[self scrollViewDidEndScrollingAnimation:self.scrollView];
}
@end