黑马程序员技术交流社区

标题: iOS如何实现图片的无限平滑轮播 原理 具体怎样实现 [打印本页]

作者: 上帝的天使    时间: 2016-5-23 10:35
标题: iOS如何实现图片的无限平滑轮播 原理 具体怎样实现
之前有写过图片的定时无限轮播,不过无法做到平滑的效果(当图片显示到最后一张后会立刻跳转到第一页。而不是平滑的显示第一页)。
下有实现源码,不过在以(//********)为分割线的内部也既是对方法(- (void)scrollViewDidScroll:(UIScrollView *)scrollView)的算法实现不是很理解,不明白为什么,望大神指教。
轮播器是这样的:

// 1.添加5张图片到scrollView中
    for (NSInteger i = 0; i < IMAGECOUNT; i++) {
        UIImageView *imageView = [[UIImageView alloc] init];
        
        // 设置frame
        CGFloat imageX = i * imageW + imageW;
//        CGFloat imageX = i * imageW;
//        NSLog(@"imageX= %f i= %ld",imageX,i);
        
        imageView.frame = CGRectMake(imageX , imageY, imageW, imageH);
        // 设置图片
        NSString *name = [NSString stringWithFormat:@"ad_0%ld", i];
        imageView.image = [UIImage imageNamed:name];
        
        [self.scrollView addSubview:imageView];
    }
   
    // 1.1 将最后一张图片放在第0个位置
    UIImageView *lastImage = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"ad_04"]];
    lastImage.frame = CGRectMake(0, 0, imageW, imageH);
    [self.scrollView addSubview:lastImage];
   
    // 1.2 将第一张图片放在最后1页
    UIImageView *firstImage = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"ad_00"]];
    firstImage.frame = CGRectMake((IMAGECOUNT + 1) * imageW, 0, imageW, imageH);
    [self.scrollView addSubview:firstImage];
   
   
    // 2.设置内容尺寸
    CGFloat contentW = (IMAGECOUNT + 2) * imageW;
    self.scrollView.contentSize = CGSizeMake(contentW, 0);
   
    // 3.隐藏水平滚动条
//    self.scrollView.showsHorizontalScrollIndicator = NO;
   
    // 4.分页
    self.scrollView.pagingEnabled = YES;
   
    // 5.设置pageControl的总页数
    self.pageControl.numberOfPages = IMAGECOUNT;
   
    [self.scrollView setContentOffset:CGPointMake(imageW, 0)];
    NSLog(@"offset= %@",NSStringFromCGPoint(self.scrollView.contentOffset));
   
    self.pageControl.currentPage = 0;
   
    // 6.添加定时器(每隔2秒调用一次self 的nextImage方法)
    [self addTimer];
}

/**
*  添加定时器
*/
- (void)addTimer
{
    self.timer = [NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(nextImage) userInfo:nil repeats:YES];
    [[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes];
}

/**
*  移除定时器
*/
- (void)removeTimer
{
    [self.timer invalidate];
    self.timer = nil;
}

- (void)nextImage{
    // 1.增加pageControl的页码
    NSInteger page = self.pageControl.currentPage + 2; // 1
//    NSLog(@"page= %ld",page);
    // 2.计算scrollView滚动的位置
    CGFloat offsetX = page * self.scrollView.frame.size.width; // 600
    NSLog(@"currentPage= %ld,offsetX= %f,page= %ld",(long)self.pageControl.currentPage,offsetX,page);
    CGPoint offset = CGPointMake(offsetX, 0);
    [self.scrollView setContentOffset:offset animated:YES];
   
}

#pragma mark - 代理方法
/**
*  当scrollView正在滚动就会调用
*/
//***************************************
//***************************************
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    // 根据scrollView的滚动位置决定pageControl显示第几页
    CGFloat scrollW = scrollView.frame.size.width;
    NSInteger page = (scrollView.contentOffset.x + scrollW * 0.5) / scrollW;
    //    if (page > 5) {
    //        self.pageControl.currentPage = 0;
    //    }else if (page == 0) {
    //        self.pageControl.currentPage = 5;
    //    } else {
    //        self.pageControl.currentPage = --page;
    //    }
   
    page = (--page == 5) ? 0 : page;
    self.pageControl.currentPage = (page == -1) ? 5 : page;
}
//***************************************
//***************************************
/**
*  开始拖拽的时候调用
*/
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
    // 停止定时器(一旦定时器停止了,就不能再使用)
    [self removeTimer];
}

/**
*  停止拖拽的时候调用
*/
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
    // 开启定时器
    [self addTimer];
}

/** 当动画滚动时,动画结束,也就是滚动一页停止之后,会调用此方法 */
- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView{
    [self scrollViewDidStop:scrollView];
}

/** 手动滚动时,当降速完也,也就是滚动一页停止之后,会调用此方法 */
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{
    [self scrollViewDidStop:scrollView];
}

/**
*  当停止滚动的时候调用
*/
-(void)scrollViewDidStop:(UIScrollView *)scrollView{
    CGFloat scrollW = scrollView.frame.size.width;
    NSInteger page = (self.scrollView.contentOffset.x + 0.5 * scrollW) / scrollW;
    if (page == 0){
        [self.scrollView setContentOffset:CGPointMake(scrollW * IMAGECOUNT, 0)];
    } else if (page == (IMAGECOUNT + 1)) {
        [self.scrollView setContentOffset:CGPointMake(scrollW , 0)];
    }
}





欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2