UIScrollView无缝衔接广告轮播

2016-10-22  本文已影响0人  万梦侠

思路

为了实现广告轮播页首尾无缝衔接,我们要在创建完原有图片的基础上在第一张图片前面创建imageView显示最后一张图片,在最后一张图片后面创建imageView显示第一张图片,这样在最后一张往后滑,第一张往前滑,然后再经过计算修改scrollView的contentOffset,就可以实现轮播页的 首尾无缝衔接。

具体实现

1,首先创建scrollView,这里使用懒加载进行创建

- (UIScrollView *)scrollView {
    if (!_scrollView) {
        UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:self.bounds];
        //初始contentOffset为self.frame.size.width
        scrollView.contentOffset = CGPointMake(self.frame.size.width, 0);
        //contentSize的width为图片的数量加2,因为头尾各多加了一张图片
        scrollView.contentSize = CGSizeMake(self.frame.size.width*(_images.count+2), self.frame.size.height);
        scrollView.pagingEnabled = YES;
        scrollView.showsHorizontalScrollIndicator = NO;
        scrollView.showsVerticalScrollIndicator = NO;
        scrollView.bounces = NO;
        scrollView.delegate = self;
        
        [self addSubview:scrollView];
        
        _scrollView = scrollView;
    }
    return _scrollView;
}

2,懒加载创建imageView

- (void)createImageViews {
    for (NSInteger i = 0; i < _images.count + 2; i++) {
        UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(self.frame.size.width*i, 0, self.frame.size.width, self.frame.size.height)];
        //创建self.images.count + 2个imageView,为了实现左右滑动无缝连接,除了正常的图片之外,在第一张之前加上最后一张,在最后一张后加上第一张
        if (i == 0) {
            imageView.image = _images[_images.count-1];
        } else if (i == _images.count + 1) {
            imageView.image = _images[0];
        } else {
            imageView.image = _images[i - 1];
        }
        [self.scrollView addSubview:imageView];
    }
}

3,懒加载创建pageControl

- (UIPageControl *)pageControl {
    if (!_pageControl) {
        UIPageControl *pageControl = [[UIPageControl alloc] init];
        
        pageControl.numberOfPages = self.images.count;
        
        self.currentPage = 0;
        
        pageControl.hidden = !self.isPageControlNeed;
        
        pageControl.currentPage = self.currentPage;
        
        CGSize pageControlSize = [pageControl sizeForNumberOfPages:self.images.count];
        
        pageControl.frame = CGRectMake((self.frame.size.width - pageControlSize.width)/2, self.frame.size.height - 50, pageControlSize.width, pageControlSize.height);
        
        [self addSubview:pageControl];
        
        _pageControl = pageControl;
        
    }
    return _pageControl;
}

4,懒加载创建定时器,为了防止滑动界面的时候定时器停止,把定时器的mode设置成NSRunLoopCommonModes

- (NSTimer *)timer {
    if (!_timer) {
        //创建定时器前先删除,可以防止多次创建
        [_timer invalidate];
        //创建定时器
        NSTimer *timer = [NSTimer timerWithTimeInterval:_timeInterval target:self selector:@selector(imageScroll) userInfo:nil repeats:YES];
        //添加到当前RunLoop中,设置模式为NSRunLoopCommonModes,可以防止滑动界面的时候定时器停止
        [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
        _timer = timer;
    }
    return _timer;
}

5,设置定时器的滚动动画,每次执行当前页面加一,在block里修改contentOffSet,执行动画,然后判断是否是最后一张图片,如果是,重设currentPage,contentOffset。

//滚动动画
- (void)imageScroll {
    self.currentPage++;
    //执行动画
    [UIView animateWithDuration:self.scrollAnimateDuration animations:^{
        self.scrollView.contentOffset = CGPointMake(self.frame.size.width*(_currentPage+1), 0);
    }];
    if (self.currentPage == self.images.count) {
        self.currentPage = 0;
        self.scrollView.contentOffset = CGPointMake(self.frame.size.width*(_currentPage+1), 0);
        ;
    }
    self.pageControl.currentPage = self.currentPage;
}

6,上面已经设定好自动滚动的功能,下面我们要考虑手动滑动的逻辑判断,首先我们要遵守UIScrollViewDelegate协议,然后实现其代理,在滑动结束后,判断当前坐标,然后修改currentPage,如果在最后一页或者第一页,则修改contentOffset

#pragma mark - UIScrollViewDelegate
//设置代理轮动完成后触发
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
    NSInteger offSet = scrollView.contentOffset.x;
    //判断是否为最后一页
    if (offSet == self.frame.size.width*(self.images.count+1)) {
        offSet = self.frame.size.width;
        self.scrollView.contentOffset = CGPointMake(offSet, 0);
        self.currentPage = 0;
    }
  //判断是否为第一页
   else if (offSet == 0) {
        offSet = self.frame.size.width*self.images.count;
        self.scrollView.contentOffset = CGPointMake(offSet, 0);
        self.currentPage = self.images.count - 1;
    } 
  //其它情况
  else {
        self.scrollView.contentOffset = CGPointMake(offSet, 0);
        self.currentPage = offSet/self.frame.size.width - 1;
    }
    self.pageControl.currentPage = self.currentPage;
}

到这里为止一个无缝衔接的广告滚动页就完成了,有任何疑问请留言
Github:https://github.com/tinybird00/ZSXScrollAdView

上一篇 下一篇

猜你喜欢

热点阅读