iOS开发经常会用到UIScrollView,而能够平滑的展示划动效果,是至关重要的。但,经常会在划动到中间位置的时候,出现卡顿,很影响用户体验性。因此,个人把个人的一些经验整理下,用代码说话,一目了然。
2、在- (void)scrollViewDidScroll:(UIScrollView *)sender方法中进行页面更新。
函数refreshPageViewAfterPaged是页面的更新操作判断。
现在UIScrollView使用有两种方法:一种是App Dev里面的Sample,建立一个包含页面数据的数组,划动的同时,不断添加和删除其他页。而另外一种是定义三个页面,划动过程中,类似与木板搭桥过河游戏一样,prev->current->next->prev,只需重新加载新载入的页面。
1、创建UIScrollView和三个自定义的View:
- scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 54, TOP_BIG_IMAGE_WIDTH, TOP_BIG_IMAGE_HEIGHT)];
- scrollView.autoresizingMask = UIViewAutoresizingFlexibleWidth;
- <span style="white-space:pre"> </span>self.scrollView.contentSize = CGSizeMake(numberOfPages * self.scrollView.frame.size.width,
- self.scrollView.frame.size.height);
- self.scrollView.delegate = self;
- scrollView.autoresizesSubviews = YES;
- scrollView.pagingEnabled = YES;
- scrollView.showsHorizontalScrollIndicator = NO;
- scrollView.scrollsToTop = NO;
- [selfView addSubview:scrollView];
三个自定义View。函数setPageContentWithPageView:(CustomView *)pageView withPageNumber:(NSInteger)pageNumber,是对customview进行更新操作的代码。
- prevPageView = [[CustomView alloc] initWithFrame:CGRectMake(0, 0, self.scrollView.frame.size.width,
- self.scrollView.frame.size.height)];
- currentPageView = [[CustomView alloc] initWithFrame:CGRectMake(0, 0, self.scrollView.frame.size.width,
- self.scrollView.frame.size.height)];
- nextPageView = [[CustomView alloc] initWithFrame:CGRectMake(0, 0, self.scrollView.frame.size.width,
- self.scrollView.frame.size.height)];
- CGFloat pageWidth = self.scrollView.frame.size.width;
- CGFloat pageHeight = self.scrollView.frame.size.height;
- currentPageView.frame = CGRectMake(currentPage * pageWidth, 0, pageWidth, pageHeight);
- [self setPageContentWithPageView:currentPageView withPageNumber:currentPage];
- //第一页
- if (currentPage == 0)
- {
- prevPageView.frame = CGRectZero;
- nextPageView.frame = CGRectMake(((currentPage + 1) * pageWidth), 0, pageWidth, pageHeight);
- if (numberOfPages - 1 >= currentPage + 1)
- {
- [self setPageContentWithPageView:nextPageView withPageNumber:currentPage + 1];
- }
- }
- //最后一页
- else if (currentPage == numberOfPages - 1)
- {
- prevPageView.frame = CGRectMake(((currentPage - 1) * pageWidth), 0, pageWidth, pageHeight);
- nextPageView.frame = CGRectZero;
- [self setPageContentWithPageView:prevPageView withPageNumber:currentPage - 1];
- }
- else
- {
- prevPageView.frame = CGRectMake(((currentPage - 1) * pageWidth), 0, pageWidth, pageHeight);
- nextPageView.frame = CGRectMake(((currentPage + 1) * pageWidth), 0, pageWidth, pageHeight);
- [self setPageContentWithPageView:prevPageView withPageNumber:currentPage - 1];
- [self setPageContentWithPageView:nextPageView withPageNumber:currentPage + 1];
- }
- [self.scrollView addSubview:currentPageView];
- [self.scrollView addSubview:prevPageView];
- [self.scrollView addSubview:nextPageView];
- oint offset = CGPointMake(currentPage * self.scrollView.frame.size.width, 0);
- [self.scrollView setContentOffset:offset animated:NO];
2、在- (void)scrollViewDidScroll:(UIScrollView *)sender方法中进行页面更新。
- #pragma mark -
- #pragma mark UIScrollViewDelegate Methods
- - (void)scrollViewDidScroll:(UIScrollView *)sender
- {
- CGFloat pageWidth = self.scrollView.frame.size.width;
- NSInteger page = floor((self.scrollView.contentOffset.x - pageWidth/2) / pageWidth) + 1;
- // 已经是第一页再往向前翻页,或者已经是最后一页再往后翻页。
- if (currentPage == page || page < 0 || page >= numberOfPages)
- {
- return;
- }
- else
- {
- //先赋值,防止scrollView在执行线程后还未执行currentPage = page,导致不断进入该段代码区执行
- NSInteger prevPage = currentPage;
- currentPage = page;
- //防止用户快速滑动,出现因线程未加载完,出现空百夜
- self.scrollView.userInteractionEnabled = NO;
- //线程处理,使得加载动作不会阻塞主线程而出现卡顿。注意,不加afterDelay:0.1,线程会立刻执行,卡顿会出现。
- [self performSelector:@selector(refreshPageViewAfterPaged:)
- withObject:[NSNumber numberWithInteger:prevPage]
- afterDelay:0.1];
- }
- }
函数refreshPageViewAfterPaged是页面的更新操作判断。
- - (void)refreshPageViewAfterPaged:(NSNumber *)prevPageNumber
- {
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- self.scrollView.userInteractionEnabled = YES;
- CGFloat pageWidth = self.scrollView.frame.size.width;
- CGFloat pageHeight = self.scrollView.frame.size.height;
- NSInteger prevPage = [prevPageNumber integerValue];
- //页面向后滑动一页
- TopPicView *tempPageView = nil;
- if (currentPage - 1 == prevPage)
- {
- tempPageView = currentPageView;
- currentPageView = nextPageView;
- nextPageView = prevPageView;
- prevPageView = tempPageView;
- prevPageView.frame = CGRectMake(((currentPage - 1) * pageWidth), 0, pageWidth, pageHeight);
- currentPageView.frame = CGRectMake(currentPage * pageWidth, 0, pageWidth, pageHeight);
- if (currentPage == (numberOfPages - 1))
- {
- nextPageView.frame = CGRectZero;
- }
- else
- {
- nextPageView.frame = CGRectMake(((currentPage + 1) * pageWidth), 0, pageWidth, pageHeight);
- //页面更新操作的实质代码:
- [self setPageContentWithPageView:nextPageView withPageNumber:currentPage + 1];
- }
- }
- else if (currentPage + 1 == prevPage)
- {
- tempPageView = currentPageView;
- currentPageView = prevPageView;
- prevPageView = nextPageView;
- nextPageView = tempPageView;
- currentPageView.frame = CGRectMake(currentPage * pageWidth, 0, pageWidth, pageHeight);
- nextPageView.frame = CGRectMake(((currentPage + 1) * pageWidth), 0, pageWidth, pageHeight);
- if (currentPage == 0)
- {
- prevPageView.frame = CGRectZero;
- }
- else
- {
- prevPageView.frame = CGRectMake(((currentPage - 1) * pageWidth), 0, pageWidth, pageHeight);
- [self setPageContentWithPageView:prevPageView withPageNumber:currentPage - 1];
- }
- }
- [pool release];
- }