读书人

UIScrollView 平滑划动处置

发布时间: 2012-07-04 19:33:54 作者: rapoo

UIScrollView 平滑划动处理

原文链接,请支持原作者:http://blog.csdn.net/gavinming/article/details/6745988

?iOS开发经常会用到UIScrollView,而能够平滑的展示划动效果,是至关重要的。比较常用的方法有两种:

? ? ? 1)将所有的scrollview子页面都add到scrollview中,这样可以平滑滑动,但占用资源加多,并且初始化加载比较慢。

? ? ? 2)使用三个页面View,在滑动过程中如指针轮询那样交替使用。优点是占用内存少,但如果单个页面比较大,经常会在划动到中间位置的时候,出现卡顿,很影响用户体验性。

?

? ? ? 第一种方法就不多讲解,如果页面不多,并且每个页面加载的资源也比较少,那么建议采用第一种方式。如果页面比较多,资源比较大,则建议采用延迟加载的方式。


?

?更优的方法,请查看:《优化——UIScrollView通过内容延迟加载以达到平滑滑动。


? ? ? 现在UIScrollView使用有两种方法:一种是App Dev里面的Sample,建立一个包含页面数据的数组,划动的同时,不断添加和删除其他页。而另外一种是定义三个页面,划动过程中,类似与木板搭桥过河游戏一样,prev->current->next->prev,只需重新加载新载入的页面。

1、创建UIScrollView和三个自定义的View:

?

[cpp]?view plaincopy
  1. ????//***********************************UIScrollView***********************************/??
  2. ????scrollView?=?[[UIScrollView?alloc]?initWithFrame:CGRectMake(0,?54,?TOP_BIG_IMAGE_WIDTH,?TOP_BIG_IMAGE_HEIGHT)];??
  3. ????scrollView.autoresizingMask?=?UIViewAutoresizingFlexibleWidth;??
  4. <span?style="white-space:pre">????</span>self.scrollView.contentSize?=?CGSizeMake(numberOfPages?*?self.scrollView.frame.size.width,???
  5. ?????????????????????????????????????????????self.scrollView.frame.size.height);??
  6. ????self.scrollView.delegate?=?self;??
  7. ????scrollView.autoresizesSubviews?=?YES;??
  8. ????scrollView.pagingEnabled?=?YES;??
  9. ????scrollView.showsHorizontalScrollIndicator?=?NO;??
  10. ????scrollView.scrollsToTop?=?NO;??
  11. ????[selfView?addSubview:scrollView];??


?

三个自定义View。函数setPageContentWithPageView:(CustomView *)pageView withPageNumber:(NSInteger)pageNumber,是对customview进行更新操作的代码。

?

[cpp]?view plaincopy
  1. prevPageView?=?[[CustomView?alloc]?initWithFrame:CGRectMake(0,?0,?self.scrollView.frame.size.width,??
  2. ????????????????????????????????????????????????????????????self.scrollView.frame.size.height)];??
  3. currentPageView?=?[[CustomView?alloc]?initWithFrame:CGRectMake(0,?0,?self.scrollView.frame.size.width,??
  4. ???????????????????????????????????????????????????????????????self.scrollView.frame.size.height)];??
  5. nextPageView?=?[[CustomView?alloc]?initWithFrame:CGRectMake(0,?0,?self.scrollView.frame.size.width,??
  6. ????????????????????????????????????????????????????????????self.scrollView.frame.size.height)];??
  7. CGFloat?pageWidth?=?self.scrollView.frame.size.width;??
  8. CGFloat?pageHeight?=?self.scrollView.frame.size.height;??
  9. ??
  10. currentPageView.frame?=?CGRectMake(currentPage?*?pageWidth,?0,?pageWidth,?pageHeight);??
  11. [self?setPageContentWithPageView:currentPageView?withPageNumber:currentPage];??
  12. ??
  13. //第一页??
  14. if?(currentPage?==?0)??
  15. {??
  16. ????prevPageView.frame?=?CGRectZero;??
  17. ????nextPageView.frame?=?CGRectMake(((currentPage?+?1)?*?pageWidth),?0,?pageWidth,?pageHeight);??
  18. ??????
  19. ????if?(numberOfPages?-?1?>=?currentPage?+?1)??
  20. ????{??
  21. ????????[self?setPageContentWithPageView:nextPageView?withPageNumber:currentPage?+?1];??
  22. ????}??
  23. }??
  24. //最后一页??
  25. else?if?(currentPage?==?numberOfPages?-?1)??
  26. {??
  27. ????prevPageView.frame?=?CGRectMake(((currentPage?-?1)?*?pageWidth),?0,?pageWidth,?pageHeight);??
  28. ????nextPageView.frame?=?CGRectZero;??
  29. ????[self?setPageContentWithPageView:prevPageView?withPageNumber:currentPage?-?1];??
  30. }??
  31. else??
  32. {??
  33. ????prevPageView.frame?=?CGRectMake(((currentPage?-?1)?*?pageWidth),?0,?pageWidth,?pageHeight);???
  34. ????nextPageView.frame?=?CGRectMake(((currentPage?+?1)?*?pageWidth),?0,?pageWidth,?pageHeight);??
  35. ????[self?setPageContentWithPageView:prevPageView?withPageNumber:currentPage?-?1];??
  36. ????[self?setPageContentWithPageView:nextPageView?withPageNumber:currentPage?+?1];??
  37. }??
  38. ??
  39. [self.scrollView?addSubview:currentPageView];??
  40. [self.scrollView?addSubview:prevPageView];??
  41. [self.scrollView?addSubview:nextPageView];??
  42. ??
  43. oint?offset?=?CGPointMake(currentPage?*?self.scrollView.frame.size.width,?0);??
  44. [self.scrollView?setContentOffset:offset?animated:NO];??


2、在- (void)scrollViewDidScroll:(UIScrollView *)sender方法中进行页面更新。

?

?

[cpp]?view plaincopy
  1. #pragma?mark?-??
  2. #pragma?mark?UIScrollViewDelegate?Methods??
  3. ??
  4. -?(void)scrollViewDidScroll:(UIScrollView?*)sender??
  5. {??
  6. ????CGFloat?pageWidth?=?self.scrollView.frame.size.width;??
  7. ????NSInteger?page?=?floor((self.scrollView.contentOffset.x?-?pageWidth/2)?/?pageWidth)?+?1;??
  8. ??????
  9. ????//??已经是第一页再往向前翻页,或者已经是最后一页再往后翻页。??
  10. ????if?(currentPage?==?page?||?page?<?0?||?page?>=?numberOfPages)??
  11. ????{??????????
  12. ????????return;??
  13. ????}??
  14. ????else??
  15. ????{??
  16. ????????//先赋值,防止scrollView在执行线程后还未执行currentPage?=?page,导致不断进入该段代码区执行???
  17. ????????NSInteger?prevPage?=?currentPage;??
  18. ????????currentPage?=?page;??
  19. ??????????
  20. ????????//防止用户快速滑动,出现因线程未加载完,出现空百夜??
  21. ????????self.scrollView.userInteractionEnabled?=?NO;??
  22. ????????//线程处理,使得加载动作不会阻塞主线程而出现卡顿。注意,不加afterDelay:0.1,线程会立刻执行,卡顿会出现。??
  23. ????????[self?performSelector:@selector(refreshPageViewAfterPaged:)??
  24. ???????????????????withObject:[NSNumber?numberWithInteger:prevPage]??
  25. ???????????????????afterDelay:0.1];??
  26. ????}??
  27. }??


函数refreshPageViewAfterPaged是页面的更新操作判断。

?

?

[cpp]?view plaincopy
  1. -?(void)refreshPageViewAfterPaged:(NSNumber?*)prevPageNumber??
  2. {??
  3. ????NSAutoreleasePool?*pool??=?[[NSAutoreleasePool?alloc]?init];??
  4. ??????
  5. ????self.scrollView.userInteractionEnabled?=?YES;??
  6. ??????
  7. ????CGFloat?pageWidth?=?self.scrollView.frame.size.width;??
  8. ????CGFloat?pageHeight?=?self.scrollView.frame.size.height;??
  9. ??
  10. ????NSInteger?prevPage?=?[prevPageNumber?integerValue];??
  11. ????//页面向后滑动一页??
  12. ????TopPicView?*tempPageView?=?nil;??
  13. ????if?(currentPage?-?1?==?prevPage)??
  14. ????{??
  15. ????????tempPageView?=?currentPageView;??
  16. ????????currentPageView?=?nextPageView;??
  17. ????????nextPageView?=?prevPageView;??
  18. ????????prevPageView?=?tempPageView;??
  19. ??????????
  20. ????????prevPageView.frame?=?CGRectMake(((currentPage?-?1)?*?pageWidth),?0,?pageWidth,?pageHeight);??
  21. ????????currentPageView.frame?=?CGRectMake(currentPage?*?pageWidth,?0,?pageWidth,?pageHeight);??
  22. ??????????
  23. ????????if?(currentPage?==?(numberOfPages?-?1))??
  24. ????????{??
  25. ????????????nextPageView.frame?=?CGRectZero;??
  26. ????????}??
  27. ????????else??
  28. ????????{??
  29. ????????????nextPageView.frame?=?CGRectMake(((currentPage?+?1)?*?pageWidth),?0,?pageWidth,?pageHeight);??
  30. ????????????//页面更新操作的实质代码:??
  31. ????????????[self?setPageContentWithPageView:nextPageView?withPageNumber:currentPage?+?1];??
  32. ????????}??
  33. ??????????
  34. ??????????
  35. ????}??
  36. ????else?if?(currentPage?+?1?==?prevPage)??
  37. ????{??
  38. ????????tempPageView?=?currentPageView;??
  39. ????????currentPageView?=?prevPageView;??
  40. ????????prevPageView?=?nextPageView;??
  41. ????????nextPageView?=?tempPageView;??
  42. ??????????
  43. ????????currentPageView.frame?=?CGRectMake(currentPage?*?pageWidth,?0,?pageWidth,?pageHeight);??
  44. ????????nextPageView.frame?=?CGRectMake(((currentPage?+?1)?*?pageWidth),?0,?pageWidth,?pageHeight);??
  45. ??????????
  46. ????????if?(currentPage?==?0)??
  47. ????????{??
  48. ????????????prevPageView.frame?=?CGRectZero;??
  49. ????????}??
  50. ????????else??
  51. ????????{??
  52. ????????????prevPageView.frame?=?CGRectMake(((currentPage?-?1)?*?pageWidth),?0,?pageWidth,?pageHeight);??
  53. ????????????[self?setPageContentWithPageView:prevPageView?withPageNumber:currentPage?-?1];??
  54. ????????}??
  55. ????}??
  56. ??
  57. ????[pool?release];??
  58. }??

读书人网 >移动开发

热点推荐