2014-04-01 76 views
5

因此,人們在這個特定事件中遇到的大多數問題是在發生動畫時觸發scrollViewDidScroll。我的情況正好相反。我覺得scrollViewDidScroll不應該在我的情況下被解僱。UITableView scrollViewDidScroll動畫

讓我進一步解釋。

我在scrollViewDidScroll中設置動畫效果,直到我將UITableView移動到UIView類中時,它才能正常工作。

- (void) scrollViewDidScroll:(UIScrollView *)scrollView { 
    // Animation code here. 
    NSLog(@"scrollViewDidScroll"); 
} 

- (void) scrollViewDidEndDecelerating:(UIScrollView *)scrollView { 
    NSLog(@"scrollViewDidEndDecelerating"); 
    NSArray *indexPaths = [_myTableView indexPathsForVisibleRows]; 
    [_myTableView scrollToRowAtIndexPath:[indexPaths objectAtIndex:0] atScrollPosition:UITableViewScrollPositionTop animated:YES]; 
} 


這是什麼提供的是一個平滑滾動的經驗,彈回先前的錶行。由於scrollToRowAtIndexPath,控制檯可以驗證scrollViewDidScroll事件正在觸發。

控制檯:

2014-03-31 22:21:43.346 Project[45843:a0b] scrollViewDidScroll 
2014-03-31 22:21:43.379 Project[45843:a0b] scrollViewDidScroll 
2014-03-31 22:21:43.429 Project[45843:a0b] scrollViewDidScroll 
2014-03-31 22:21:43.462 Project[45843:a0b] scrollViewDidScroll 
2014-03-31 22:21:43.479 Project[45843:a0b] scrollViewDidEndDecelerating 
2014-03-31 22:21:43.496 Project[45843:a0b] scrollViewDidScroll 
2014-03-31 22:21:43.513 Project[45843:a0b] scrollViewDidScroll 
2014-03-31 22:21:43.529 Project[45843:a0b] scrollViewDidScroll 

走上問題:

1.如何確保該事件scrollViewDidScroll只是由於用戶交互火災,而不是從代碼自動化?

2.是否有另一種方法可以提供與scrollToRowAtIndexPath相同的功能,而不會觸發scrollViewDidScroll

+1

按我的知識,你不能沒有委託方法滾動被調用。你可以做的一件事是通過以編程方式滾動,你可以設置一個標誌並在委託方法中使用它。如果以編程方式滾動重置標誌。我希望這會幫助你.. –

回答

13

我知道這是一個非常古老的問題。我只是遇到類似的情況,我只需要在用戶滾動時運行一些代碼,而不是在我撥打scrollToRowAtIndexPath時運行一些代碼。我發現使用scrollView變量draggingdecelerating更容易的解決方案。

我們在這裏有3種滾動情況。

  1. 用戶拖動
  2. 用戶剛剛結束拖動和實現代碼如下是decelrating
  3. 編程稱爲scrollForRowAtIndexPath:

所有病例上面會觸發scrollViewDidScroll:

  1. 用戶正在拖動draggingdecelerating
  2. 用戶剛剛結束拖動和實現代碼如下是decelrating draggingdecelerating
  3. 編程稱爲scrollForRowAtIndexPath:draggingdecelerating

所以你的代碼會像這樣的事情:

- (void) scrollViewDidScroll:(UIScrollView *)scrollView { 
    if (scrollView.dragging) 
    { 
     // Do what you want when user is dragging 
    } else if (scrollView.decelerating) 
    { 
     // Do what you want when table is decelerating after finished dragging 
    } else 
    { 
     // Do what you want when table is scrolling programmatically. 
    } 
} 

或者,如果你只想區分progammatically滾動

- (void) scrollViewDidScroll:(UIScrollView *)scrollView { 
    if (scrollView.dragging || scrollView.decelerating) 
    { 
     // Scrolling by the user 
    } else 
    { 
     // Scrolling by the code 
    } 
} 
+2

這是一個比滾動我的更優雅的解決方案!將此更改爲接受的答案。 –

1

我發佈了這個問題後不久,我休息了一小會兒,回到了問題中並找出答案。應該儘快完成,而不是浪費幾個小時。的Bleh!

解決方法很簡單,設置得到任何綱領性滾動之前設置,然後更改該動畫使用事件scrollViewDidEndScrollingAnimation完成後bool標誌。

bool performingAutomatedScroll = false; 

- (void) scrollViewDidScroll:(UIScrollView *)scrollView { 

    // If we are scrolling because of code, don't use any animations. 
    if (performingAutomatedScroll) return; 

    // Animation code here. 
} 

- (void) scrollViewDidEndDecelerating:(UIScrollView *)scrollView { 

    performingAutomatedScroll = true; 
    NSArray *indexPaths = [_myTableView indexPathsForVisibleRows]; 
    [_myTableView scrollToRowAtIndexPath:[indexPaths objectAtIndex:0] atScrollPosition:UITableViewScrollPositionTop animated:YES]; 
    [_myTableView reloadRowsAtIndexPaths:[_timeCarousel indexPathsForVisibleRows] withRowAnimation:UITableViewRowAnimationNone]; 

} 

- (void) scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate { 

    if (!decelerate) { 
    performingAutomatedScroll = true; 
    NSArray *indexPaths = [_myTableView indexPathsForVisibleRows]; 
    [_myTableView scrollToRowAtIndexPath:[indexPaths objectAtIndex:0] atScrollPosition:UITableViewScrollPositionTop animated:YES]; 
    [_myTableView reloadRowsAtIndexPaths:[_timeCarousel indexPathsForVisibleRows] withRowAnimation:UITableViewRowAnimationNone]; 
    } 

} 

-(void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView { 
    performingAutomatedScroll = false; 
}