标签:循环滚动 interface content import 最好
头文件:
#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 【屏幕】
无缝循环实现了。
标签:循环滚动 interface content import 最好
原文地址:http://9178487.blog.51cto.com/9168487/1547647