So most of the problems people have with this particular event is to have scrollViewDidScroll
fire when there is animation happening. My case is just the opposite. I feel that scrollViewDidScroll
should NOT be firing in my case.
Let me further explain.
I am animating things in scrollViewDidScroll and this was working perfectly until I moved UITableView into a UIView class.
- (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];
}
What this provides is a smooth scrolling experience that snaps back to a previous table row. The console can verify that scrollViewDidScroll
event is firing because of scrollToRowAtIndexPath
.
Console:
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
Onto the questions:
1. How can I ensure that the event scrollViewDidScroll
only fires due to user interaction and not automation from code?
2. Is there another method that provides the same functionality as scrollToRowAtIndexPath
without triggering scrollViewDidScroll
?
contentOffset is the point at which the origin of the content view is offset from the origin of the scroll view. In other words, it is where the user has currently scrolled within the scroll view. This obviously changes as the user scrolls.
Overview. UIScrollView is the superclass of several UIKit classes, including UITableView and UITextView . A scroll view is a view with an origin that's adjustable over the content view. It clips the content to its frame, which generally (but not necessarily) coincides with that of the app's main window.
→ UIScrollView has 3 main properties, known as contentSize, contentOffset, and contentInset.
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 False
dragging
is False and decelerating
is True
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
}
}
Soon after I posted the question, I took a small break, came back to the problem and figured it out. Should of done that sooner instead of wasting a few hours. bleh!
The solution is simple, set a bool
flag that gets set before any progammatic scrolling and then change that after the animation is done using the event 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;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With