美文网首页
UIScrollView无缝衔接广告轮播

UIScrollView无缝衔接广告轮播

作者: 万梦侠 | 来源:发表于2016-10-22 17:18 被阅读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

    相关文章

      网友评论

          本文标题:UIScrollView无缝衔接广告轮播

          本文链接:https://www.haomeiwen.com/subject/muxhuttx.html