2011-07-24 62 views
-2

我需要以下要求的uiscrollview實現方面的幫助:分頁帶有延遲加載的UIScrollview

1)pagingEnabled = true。
2)懶惰頁面加載。
3)頁面在後臺加載。所以我需要在第一次運行加載頁面X,然後得到通知,該頁面已完全加載,然後才允許用戶滾動到它。
4)改變當前頁面的能力。

我的第一次嘗試是重寫scrollViewDidEndDeacelerating和scrollViewDidScroll,但是我有一半的頁面出現問題(當你停止滾動一半的頁面,然後等待新頁面添加到滾動)和空白頁面(當用戶滾動得太快時)。

我的第二次嘗試是重寫UIScrollView的layoutSubviews方法,並在那裏做所有的計算。但它似乎非常複雜。

所以,我很想找到任何類似實現的例子。

現在我有這樣的代碼:

我實現scrollViewWillBeginDraggingscrollViewDidEndDecelerating

- (void)scrollViewWillBeginDragging:(UIScrollView *)aScrollView 
{ 
    isScrolling = YES; 
} 
- (void)scrollViewDidEndDecelerating:(UIScrollView *)aScrollView 
{ 
    isScrolling = NO; 
    // Here we load the page that was prepared when the user was scrolling 
    if (needDisplay > -1) { 
     //NSLog(@"Loading queued page %d", needDisplay); 
     [self loadScrollViewWithPage:needDisplay forceAddToSuperview:NO animated:YES]; 
     needDisplay = -1; 
    } 

    // minLoadedPageIndex - index of the first loaded page. 
    int selectedIndex = MIN(floor((aScrollView.contentOffset.x - pageWidth/2)/pageWidth) + 1 + minLoadedPageIndex, [photoItems count] - 1); 

    [self loadScrollViewWithPage:selectedIndex - 1 forceAddToSuperview:NO animated:YES]; 
    [self loadScrollViewWithPage:selectedIndex forceAddToSuperview:NO animated:YES]; 
    [self loadScrollViewWithPage:selectedIndex + 1 forceAddToSuperview:NO animated:YES]; 
} 

loadScrollViewWithPage我創造它加載的頁面視圖控制器來自服務器的數據在後臺。直到它從服務器加載數據之前,我不會將視圖添加到滾動視圖。

- (void)loadScrollViewWithPage:(int)page forceAddToSuperview:(BOOL)value animated:(BOOL)animated 
{ 
    DetailController *controller = page >= viewControllers.count ? [NSNull null] :[viewControllers objectAtIndex:page]; 

    if ((NSNull *)controller == [NSNull null]) 
    { 
     controller = [[DetailController alloc] initWithNibName:@"DetailController" bundle:nil];   
     controller.delegate = self; 
     controller.view.hidden = NO; //this will call viewDidLoad. 

     if (page >= viewControllers.count) { 
      [viewControllers addObject:controller]; 
     } 
     else { 
      [viewControllers replaceObjectAtIndex:page withObject:controller]; 
     } 

     [controller release]; 
    } 

    // add the controller's view to the scroll view 
    if (controller.view && controller.view.superview == nil && (controller.isLoadedOrFailed || value)) { 
     [self setNumberOfVisiblePages:visiblePagesCount+1]; 

     if (page < selectedIndex) { 
      // We are adding the page to the left of the current page, 
    // so we need to adjust the content offset. 
      CGFloat offset = (int)scrollView.contentOffset.x % (int)scrollView.frame.size.width; 
      offset = scrollView.frame.size.width * (selectedIndex - minLoadedPageIndex) + offset; 
      [scrollView setContentOffset:CGPointMake(offset, 0.0) animated:animated];  
     } 

     CGRect frame = scrollView.frame; 
     frame.origin.x = frame.size.width * (page - minLoadedPageIndex); 
     frame.origin.y = 0; 
     controller.view.frame = frame;   
     [scrollView addSubview:controller.view]; 
     [controller viewWillAppear:NO]; 
    } 
} 

另外我有一個detailControllerDidFinishDownload方法當用於頁面視圖控制器數據已經加載被調用。

- (void)detailControllerDidFinishDownload:(DetailController *)controller 
{ 

    ... //here I calculate new minLoadedPageIndex value 

// reset pages frames 
if (minLoadedPageIndex < oldMinPage) { 
     for(int i=oldMinPage;i < [viewControllers count]; i++) { 
      DetailController *detailsController = [viewControllers objectAtIndex:i]; 
      if ((NSNull *)detailsController != [NSNull null]) { 
       CGRect frame = scrollView.frame; 
       frame.origin.x = frame.size.width * (i - minLoadedPageIndex); 
       frame.origin.y = 0; 

       [detailsController.view setFrame:frame]; 
      } 
     } 
    } 

    // load the page now or delay load until the scrolling will be finished 
    if (!isScrolling) { 
     [self loadScrollViewWithPage:[photoItems indexOfObject:controller.photoItem] forceAddToSuperview:NO animated:NO]; 
    } 
    else { 
     needDisplay = [photoItems indexOfObject:controller.photoItem]; 
     //NSLog(@"pageControlUsed is used!!! %d", [photoItems indexOfObject:controller.photoItem]); 
    } 
} 

我現在的問題是,有時在頁面的中間(或接近中間的某個位置)滾動stucks,它不會去最近的頁面反彈,直到我稍微它。我的測試表明,如果我滾動出內容視圖框架(滾動視圖已彈起)並等待加載新頁面,則會發生這種情況。在10次滾動時間中的1次。

謝謝米哈伊爾!

+0

我不再需要在加載頁面時停止滾動用戶;顯示進度指示器似乎更加用戶友好,並且不需要中斷UIScrollView的行爲。 –

+0

我的客戶想要它,我無法勸他放棄它:( – MrZoidberg

回答