頭文件:
#import
@class ArticleViewController;
@interface ArticleScrollViewController : UIViewController {
//不使用數組,看起來更明了,為了節省內存同時還要看起來無縫,3個view最好
ArticleViewController *article1;
ArticleViewController *article2;
ArticleViewController *article3;
}
@end
實現:
#import "ArticleScrollViewController.h"
#import "ArticleViewController.h"
#import "ViewSwitcher.h"
@implementation ArticleScrollViewController
// vieDidLoad函數不重要,只要初始化了三個view並放在uiscrollview里面,正確設定uiscrollview的content size就行了
- (void)viewDidLoad {
[super viewDidLoad];
UIScrollView *scrollView = (UIScrollView *)self.view;
scrollView.contentSize = CGSizeMake(self.view.frame.size.width*3, self.view.frame.size.height);
CGRect frame = self.view.frame;
frame.origin.y = 0.0f;
NSInteger article2Index = [ViewSwitcher getInstance].currentArticleIndex;
NSInteger article1Index = article2Index - 1;
article1Index = article1Index < 0 ? [ViewSwitcher getInstance].articleCount - 1 : article1Index;
article1Index = article1Index >= [ViewSwitcher getInstance].articleCount ? 0 : article1Index;
NSInteger article3Index = article2Index + 1;
article3Index = article3Index < 0 ? [ViewSwitcher getInstance].articleCount - 1 : article3Index;
article3Index = article3Index >= [ViewSwitcher getInstance].articleCount ? 0 : article3Index;
article1 = [[ArticleViewController alloc] initWithArticleIndex:article1Index];
[article1.view setFrame:frame];
article2 = [[ArticleViewController alloc] initWithArticleIndex:article2Index];
frame.origin.x += self.view.frame.size.width;
[article2.view setFrame:frame];
article3 = [[ArticleViewController alloc] initWithArticleIndex:article3Index];
frame.origin.x += self.view.frame.size.width;
[article3.view setFrame:frame];
[scrollView addSubview:article1.view];
[scrollView addSubview:article2.view];
[scrollView addSubview:article3.view];
CGPoint p = CGPointZero;
p.x = scrollView.frame.size.width;
[scrollView setContentOffset:p animated:NO];
[article2 reloadData];
}
#pragma mark -
#pragma mark UIScrollViewDelegate
#define SET_FRAME(ARTICLEX) x = ARTICLEX.view.frame.origin.x + increase;\
if(x < 0) x = pageWidth * 2;\
if(x > pageWidth * 2) x = 0.0f;\
[ARTICLEX.view setFrame:CGRectMake(x, \
ARTICLEX.view.frame.origin.y,\
ARTICLEX.view.frame.size.width,\
ARTICLEX.view.frame.size.height)]
//將三個view都向右移動,並更新三個指針的指向,article2永遠指向當前顯示的view,article1是左邊的,article3是右邊的
- (void)allArticlesMoveRight:(CGFloat)pageWidth {
//上一篇
article3.articleIndex = article1.articleIndex - 1;
if (article3.articleIndex < 0) {
article3.articleIndex = [ViewSwitcher getInstance].articleCount - 1;
}
[article1 reloadData];
ArticleViewController *tmpArticleViewController = article3;
article3 = article2;
article2 = article1;
article1 = tmpArticleViewController;
float increase = pageWidth;
CGFloat x = 0.0f;
SET_FRAME(article3);
SET_FRAME(article1);
SET_FRAME(article2);
}
- (void)allArticlesMoveLeft:(CGFloat)pageWidth {
article1.articleIndex = article3.articleIndex + 1;
if (article1.articleIndex >= [ViewSwitcher getInstance].articleCount) {
article1.articleIndex = 0;
}
[article3 reloadData];//[article2 resetView];[article3 resetView];
ArticleViewController *tmpArticleViewController = article1;
article1 = article2;
article2 = article3;
article3 = tmpArticleViewController;
float increase = -pageWidth;
CGFloat x = 0.0f;
SET_FRAME(article2);
SET_FRAME(article3);
SET_FRAME(article1);
}
/*
循環滾動
每次滾動后都將scrollview的offset設置為中間的一頁
若本次滾動是向前一頁滾動,則把三頁都向后放置,最后一頁放到開頭
若本次滾動是向后一頁滾動,則把三頁都向前放置,第一頁放到末尾
*/
- (void)scrollViewDidEndDecelerating:(UIScrollView *)theScrollView
{
CGFloat pageWidth = theScrollView.frame.size.width;
// 0 1 2
int page = floor((theScrollView.contentOffset.x - pageWidth / 2) / pageWidth) + 1;
if(page == 1) {
//用戶拖動了,但是滾動事件沒有生效
return;
} else if (page == 0) {
[self allArticlesMoveRight:pageWidth];
} else {
[self allArticlesMoveLeft:pageWidth];
}
CGPoint p = CGPointZero;
p.x = pageWidth;
[theScrollView setContentOffset:p animated:NO];
[article1 resetView];
[article3 resetView];
}
#pragma mark -
#pragma mark dealloc
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc. that aren't in use.
}
- (void)viewDidUnload {
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
[article1 release];article1 = nil;
[article2 release];article2 = nil;
[article3 release];article3 = nil;
}
- (void)dealloc {
[article1 release];
[article2 release];
[article3 release];
[super dealloc];
}
@end
這里的雕蟲小技主要在於:
以手指向右拖動為例,【屏幕】指的是scorllview的顯示區域
article1 article2 article3
【屏幕】
拖動以后成這樣:
article1 article2 article3 【屏幕】
將article3放到第一個去(設定article3的frame),這是屏幕還顯示的是article1的內容
article3 article1 article2 【屏幕】
將屏幕移到中間:使用setContentOffset,禁用動畫,這樣騙過人眼
article3 article1 article2
【屏幕】
最后更新指針順序:
article1 article2 article3
【屏幕】
無縫循環實現了。
by gqzhu
http://www.dreamingwish.com/dream-2011/uiscrollview-infinite-loop-scrolling.html
