轮播图在实际应用开发使用较多,本文说明一下具体的实现过程。
一、实现轮播图的基本控件介绍。
实现轮播图需要将多张图片摆放到一个scrollview上面,一个定时器按时让scrollview跳转,一个pagecontrol展示总图片数和当前的图片索引。
#define Width (self.view.frame.size.width)
@interface scrollerViewController (){
int imageCount;
}
@property (nonatomic , strong ) UIScrollView * banner;
@property (nonatomic , strong ) UIPageControl * pageControl;
@property (nonatomic , weak ) NSTimer * time;
@end
二、界面搭建实现
对scrollview和pageControl实现懒加载,将图片通过addImages这个方法摆放到scrollview上面。
#pragma mark - life cycle
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
imageCount = 3;
[self addImages];
[self.view addSubview:self.banner];
[self.view addSubview:self.pageControl];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
懒加载方法
#pragma mark - setters and getters
- (UIPageControl *)pageControl{
if (_pageControl) {
return _pageControl;
}
_pageControl = [[UIPageControl alloc]initWithFrame:CGRectMake((Width - 60)/2, 120, 60, 20)];
_pageControl.numberOfPages = imageCount;
_pageControl.currentPage = 0;
_pageControl.pageIndicatorTintColor = [UIColor whiteColor];
_pageControl.currentPageIndicatorTintColor = [UIColor greenColor];
[_pageControl addTarget:self action:@selector(pageControlResponse:) forControlEvents:UIControlEventValueChanged];
return _pageControl;
}
- (UIScrollView *)banner{
if (_banner) {
return _banner;
}
_banner = [[UIScrollView alloc]initWithFrame:CGRectMake(0, 20, Width, 120)];
_banner.delegate = self;
_banner.showsHorizontalScrollIndicator = NO;
_banner.pagingEnabled = YES;
_banner.bounces = NO;
return _banner;
}
图片摆放到scrollview的addImages方法实现。防止滚动过程图片划出一半出现白页,自动跳转出现突兀,需要在首尾分别添加末尾最后一张图片和第一张图片。
- (void)addImages{
self.banner.contentSize = CGSizeMake(Width * (imageCount + 2), 120);
for (int i = 0 ; i < (imageCount + 2); i ++ ) {
UIImageView * image = [[UIImageView alloc]initWithFrame:CGRectMake(i * Width, 0, Width, 120)];
if (i == 0) {
image.image = [UIImage imageNamed:@"3"];
}else if (i == (imageCount + 1)) {
image.image = [UIImage imageNamed:@"1"];
}else{
image.image = [UIImage imageNamed:[NSString stringWithFormat:@"%d",i]];
}
[self.banner addSubview:image];
}
[self.banner setContentOffset:CGPointMake(Width, 0) animated:YES];
[self startTimer];
}
三、定时器的处理
为了防止滑动scrollview影响定时器,将定时器放到一个新的线程处理。
- (void)startTimer{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
self.time = [NSTimer scheduledTimerWithTimeInterval:2 target:self selector:@selector(updateTimeAction) userInfo:nil
repeats:true];
[[NSRunLoop currentRunLoop] run];
});
}
定时器每隔2秒后,scrollview展示的x轴移动一个图片宽度。如果展示到最后一张图片时跳转到第一张图片。
- (void)updateTimeAction{
CGFloat CurrentX = self.banner.contentOffset.x + Width;
[UIView animateWithDuration:0.3 animations:^{
[self.banner setContentOffset:CGPointMake(CurrentX, 0) animated:YES];
}];
if (self.banner.contentOffset.x == Width * (imageCount + 1)){
self.banner.contentOffset = CGPointMake(Width, 0);
}
}
四、scrollview代理方法实现
(1)滑动到首尾实现跳转的处理
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{
CGPoint currentPoint = scrollView.contentOffset;
if (currentPoint.x == 0) {
self.banner.contentOffset = CGPointMake(imageCount * Width, 0);
}else if(currentPoint.x == (imageCount + 1) * Width){
self.banner.contentOffset = CGPointMake(Width, 0);
}
}
(2)scrollview移动后pageControl索引更换
- (void)scrollViewDidScroll:(UIScrollView *)scrollView{
if (scrollView == self.banner) {
CGPoint currentPoint = scrollView.contentOffset;
if (currentPoint.x < scrollView.bounds.size.width/2) {
self.pageControl.currentPage = imageCount;
}else if(currentPoint.x > (imageCount + 0.5) * self.banner.bounds.size.width){
self.pageControl.currentPage = 0;
}else{
float i = currentPoint.x/scrollView.bounds.size.width;
int j = i;
if ((i - (float)j) > 0.5) {
self.pageControl.currentPage = j;
}else if((i - (float)j) < 0.5){
self.pageControl.currentPage = j - 1;
}
}
}
}
(3)拖拽scrollview时对定时器的处理
将要拖拽时需要停止计时
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView{
if (self.time) {
[self.time invalidate];
}
}
停止拖拽时打开计时
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate{
[self startTimer];
}
五、pageControl点击后的事件响应处理
#pragma mark - event response
- (void)pageControlResponse:(UIPageControl *)pageControl{
[self.banner setContentOffset:CGPointMake((self.pageControl.currentPage + 1)*Width, 0) animated:YES];
}
如有更好的实现多多沟通。