UIScrollView 平滑划动处理

 iOS开发经常会用到UIScrollView,而能够平滑的展示划动效果,是至关重要的。但,经常会在划动到中间位置的时候,出现卡顿,很影响用户体验性。因此,个人把个人的一些经验整理下,用代码说话,一目了然。

  

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

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

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

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

  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方法中进行页面更新。
  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是页面的更新操作判断。
  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. }  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值