iOS常見原理(二)-scrollerview無限循環

無限循環:



我們都知道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

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章