UITableView scrollViewDidScroll在动画上触发

时间:2014-04-01 05:29:46

标签: ios objective-c uitableview ios7 uiscrollview

因此,人们对此特定事件的大多数问题是在发生动画时scrollViewDidScroll触发。我的情况正好相反。我认为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];
}


这提供了一种平滑的滚动体验,可以快速回到上一个表格行。由于scrollViewDidScroll,控制台可以验证scrollToRowAtIndexPath事件是否正在触发。

控制台:

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

2 个答案:

答案 0 :(得分:15)

I know this is a very old question. I just have been in a similar situation that I need to run some code only when the user is scrolling but not when I call scrollToRowAtIndexPath. I have found an easier solution for this using the scrollView variables dragging and decelerating.

we have 3 cases of scrolling here.

  1. user is dragging
  2. user just ended dragging and the tableview is decelrating
  3. programmatically called scrollForRowAtIndexPath:

All of the cases above will trigger scrollViewDidScroll: but

  1. user is dragging dragging is True and decelerating is False
  2. user just ended dragging and the tableview is decelrating dragging is False and decelerating is True
  3. programmatically called scrollForRowAtIndexPath: dragging is False and decelerating is False

So your code will be like something like this:

- (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.
     }
}

Or if you want to just distinguish the scrolling progammatically

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

答案 1 :(得分:1)

我发布问题后不久,我休息了一会儿,回过头来看问题并弄清楚了。应该尽快完成,而不是浪费几个小时。的Bleh!

解决方案很简单,设置一个bool标志,在任何编程滚动之前设置,然后在使用事件scrollViewDidEndScrollingAnimation完成动画后更改。

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;
}