zoukankan      html  css  js  c++  java
  • 自动无限循环UIScrollView原理

    无限循环:



    我们都知道UIScrollView有一种很流畅的切换效果,结合UIPageControl的辅助展示效果,就可以完成一个很不错的产品介绍功能页面。那么像一些购物app中,商品展示页面无限滚动的效果是如何实现的呢?



    方法1:前后+1方法,这也最常见的一种做法。假如我们有四张需要展示的图片,我们创建了一个数组来保存图片名字,此时数组中保存的是按顺序的1.png,2.png,3.png,4.png,这四个图片名字。要实现无限循环的效果,我们需要改动一下这个数组为:4.png,1.png,2.png,3.png,4.png,1.png,我们发现在原来数组的前后分别加入了一个图片名字,即将要循环展示的下一张图片的名字。当你滑动到4.png的时候,下一张会是1.png。当你在1.png往回滑动的时候,将要出现4.png。



    好了,下面是我们的核心内容:我们发现目前数组中有6个图片,当我们从3.png滑动到4.png,又从4.png滑动到1.png的时候,我们要神不知鬼不觉的迅速切换到排在第二位的1.png。反向滑动的时候也是如此,从1.png滑动到4.png的时候,我们要神不知鬼不觉的切换到拍到倒数第二位的4.png。那么怎么样才能实现神不知鬼不觉呢?



    看下面这两个UIScrollView的实例方法:


    - (void)setContentOffset:(CGPoint)contentOffset animated:(BOOL)animated;
    - (void)scrollRectToVisible:(CGRect)rect animated:(BOOL)animated;
    这两个方法可以在animated参数为NO的时候,帮助我们迅速切换视图。



    当每一次滑动结束的时候,UIScrollViewDelegate会有一个回调方法:
    - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView;
     

    此时我们来检测是否是滑动到了我们将要出发的1.png和4.png,如果是的话,那么就悄悄调用上面两个方法中的任意一个来实现视图切换。

    实现代码如下所示:
    int currentPage = (int)self.scrollView.contentOffset.x/320;
    if (currentPage==0)
    {
        [self.scrollView scrollRectToVisible:CGRectMake(320 * [slideImages count]-2,0,320,460) animated:NO]; // 序号0,跳转到最后1页
    }
    else if (currentPage==[slideImages count]-1)
    {
        [self.scrollView scrollRectToVisible:CGRectMake(320,0,320,460) animated:NO]; // 最后+1,循环第1页
    }


    方法2:瞒天过海。此方法中无论数据源有多少个,UIScrollView只保留其中三个视图,其实这是方法1的变种。当你滑动UIScrollView的时候,无非是向前滑动,或者是向后滑动,所以能够组成无限循环的基本条件就是前、中、后 三个视图。当你每次滑动的时候我都神不知鬼不觉的切换一下这三个视图。这也是和方法1 的最主要区别。



    看看下面的区别:

    - (void)scrollViewDidEndDecelerating:(UIScrollView *)aScrollView {
        
        [_scrollView setContentOffset:CGPointMake(_scrollView.frame.size.width, 0) animated:YES];
        
    }

    我们发现每一次滑动完成之后,UIScrollView总是重新切换回默认的这一个视图。下面这个代理方法将要实现重置这三个视图:
    - (void)scrollViewDidScroll:(UIScrollView *)aScrollView {

        int x = aScrollView.contentOffset.x;
        //往下翻一张
        if(x >= (2*self.frame.size.width)) {
            [self loadData];
        }
        //往上翻
        if(x <= 0) {
            [self loadData];
        }
    }

    loadData() 的实现原理非常简单,现将UIScrollView的所有视图移除,在重新根据数据源绘图来加载到UIScrollView中。
    - (void)loadData
    {    
        //从scrollView上移除所有的subview
        NSArray *subViews = [_scrollView subviews];
        if([subViews count] != 0) {
            [subViews makeObjectsPerformSelector:@selector(removeFromSuperview)];
        }
            
        for (int i = 0; i < 3; i++) {  //只有3个视图
            UIView *v = [_curViews objectAtIndex:i];
            v.frame = CGRectOffset(v.frame, v.frame.size.width * i, 0);
            [_scrollView addSubview:v];
        }
        
        [_scrollView setContentOffset:CGPointMake(_scrollView.frame.size.width, 0)];
    }

    至于你怎么绘图就是你的事情了,我这里只是简单的分析一下。


    自动无限循环



    刚才讲解了无限循环的两种不同实现方法,下面来讲解一下如何让它自动滑动。我想大家都用过NSTimer,没错,用它来实现简单的计时器最好不过了。



    在适当位置初始化一个NSTimer,设定3秒执行一次runTimePage()方法:

       // 定时器 循环
        [NSTimer scheduledTimerWithTimeInterval:3 target:self selector:@selector(runTimePage) userInfo:nil repeats:YES];
     

    在runTimePage()方法中,我们将要实现获取当前page页数,然后跳转到下一个page。

    - (void)runTimePage
    {
        int page = pageControl.currentPage; // 获取当前的page
        page++;
        pageControl.currentPage = page > [slideImages count]-2 ? 0 : page ;
        [self.scrollView setContentOffset:CGPointMake(320*(page+1),0) animated:YES];
    }

    参考demo地址:

    demo1:http://code4app.com/ios/EScrollerView/51935e166803fac572000003

    demo2:http://code4app.com/ios/循环滚动视图/5052e6a26803fa4a0c000003

    demo3:http://code4app.com/ios/循环滚动图片/51df58a16803fadd44000000

  • 相关阅读:
    CSS盒子模型
    getContextPath、getServletPath、getRequestURI、request.getRealPath的区别
    MYSQL中的CASE WHEN END AS
    单点登录的精华总结
    git&github
    June 21st 2017 Week 25th Wednesday
    June 20th 2017 Week 25th Tuesday
    June 19th 2017 Week 25th Monday
    June 18th 2017 Week 25th Sunday
    June 17th 2017 Week 24th Saturday
  • 原文地址:https://www.cnblogs.com/luqinbin/p/4930178.html
Copyright © 2011-2022 走看看