Reputation: 1059
Does anyone know how to determine which direction a scroll view will move when the user lifts their finger, i.e. when scrollViewDidEndDragging gets called?
Specifically, when the scroll view is set to paging.
Most of the time, I can just track and check the contentOffset in scrollViewDidScroll, however, there are special cases where the user flicks the screen quickly. In some cases a LEFT-RIGHT-LEFT move will scroll to the next page, and in others, the same pattern will remain on the same page.
I'm guessing it has something to do the with acceleration (difference between the last few points) of the touch.
(I'm on iOS4.3 on an iPad)
Upvotes: 5
Views: 7818
Reputation: 255
Implement the following UIScrollViewDelegate Method. You can compare current content offset and targetContentOffset then get the direction.
-(void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset{
CGPoint newOffset = CGPointMake(targetContentOffset->x, targetContentOffset->y);
if (newOffset.x > scrollView.contentOffset.x) {
NSLog(@"Scrolling direction is left");
}else{
NSLog(@"Scrolling direction is right");
}
}
Upvotes: 2
Reputation: 676
In addition to saurin response. Her solution work fine but if you are using pagination and you are in the end of scroll content size you will have to test if we really have a scroll to the next 'page' or not:
CGPoint start, end;
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
start = scrollView.contentOffset;
}
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
end = scrollView.contentOffset;
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
if (start.x > end.x && end.x>0)
{
NSLog(@"on the previous left page");
}
if (start.x < end.x && end.x < scrollView.contentOffset.x)
{
NSLog(@"on the next right page");
}
}
Upvotes: 0
Reputation: 31
You don't use timer, which is very expensive operation. Lock the direction of your scrollView first to move only up/down and left/right [I guess that's what you want]. And then use following code to determine...
CGPoint start, end;
- (void)scrollViewWillBeginDragging:(UIScrollView *)sender {
start = self.scrollView.contentOffset;
}
- (void)scrollViewDidEndDragging:(UIScrollView *)sender willDecelerate:(BOOL)decelerate {
end = self.scrollView.contentOffset;
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)sender {
NSLog(@"%d %d",(int)start.x,(int)start.y);
NSLog(@"%d %d",(int)end.x,(int)end.y);
}
Upvotes: 3
Reputation: 366
Here is my solution works fine for me hope it helps
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
CGFloat pageWidth = scrollView.frame.size.width;
//Old Solution
//Switch the indicator when more than 30% of the previous/next page is visible
//You can vary the percentage
//int page = floor((scrollView.contentOffset.x - pageWidth * 0.3) / pageWidth) + 1;
//New Solution
_pageControl.currentPage = (int)scrollView.contentOffset.x / (int)pageWidth;
}
I quit the old solution as the new one seems more slick
Upvotes: 2
Reputation: 38213
This is a tricky one, iOS 5 has the answer, but that no good for you.
Perhaps a hacky workaround is to set a NSTimer
for a small time interval (say 0.1 seconds) after scrollViewDidEndDragging
finished. Then compare the content offsets.
If you want to know if the scroll view will actually go to the next page, perhaps you could check if the content offset has gone more than 1/2 way. You could read the content offset on scrollViewDidScroll:
and do a bit of maths to determine if its more than 1/2 way.
Upvotes: 1