因此,人们对此特定事件的大多数问题是在发生动画时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
?
答案 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.
scrollForRowAtIndexPath:
All of the cases above will trigger scrollViewDidScroll:
but
dragging
is True and decelerating
is Falsedragging
is False and decelerating
is TruescrollForRowAtIndexPath:
dragging
is False and decelerating
is FalseSo 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;
}