無限循環:
我們都知道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