Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UIScrollView not scrolling to proper location with setContentOffset:animated:

I have a series of images in a UIScrollView. When the user releases the scrolling action, I want the view to center on a single image. I have the code implemented, but the underlying behavior is incorrect. My call to setContentOffset:animated: has the correct values, but the view doesn't actually scroll to that point. Here is the output of some debugging:

2011-03-26 17:28:16.201 PivotMachine[39984:207] Dragging Beginning at: 270,   0
2011-03-26 17:28:16.322 PivotMachine[39984:207]     Dragging Ended at: 360,   0 --> 350,   0
2011-03-26 17:28:16.624 PivotMachine[39984:207]    Scrolling Ended at: 350,   0
2011-03-26 17:28:25.648 PivotMachine[39984:207] Dragging Beginning at: 447,   0

As you can see, internally, it thought it stopped dragging at 360, so properly advanced to 350, where it should have been. Visually, it is sitting around 450 instead, which it knows about when I start dragging again (yes, I know you don't get the beginning immediately, so I'm dragging very slowly to only move a couple pixels before the event).

This is the dragging code (for my UIScrollView subclass):

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
    CGPoint myLocation = self.contentOffset;
    NSLog(@"Dragging Beginning at: %3.0f, %3.0f", myLocation.x, myLocation.y);
}

- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollV
{
    CGPoint myLocation = self.contentOffset;
    NSLog(@"   Scrolling Ended at: %3.0f, %3.0f", myLocation.x, myLocation.y);
}

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
    // Auto-scroll to the center of the closest menu
    if (scrollView != self)
    {
        DLog(@"[ScrollMenu scrollViewWillBeginDecelerating] called with non-self");
        return;
    }
    CGPoint myLocation = self.contentOffset;
    int idx = [self indexOfMenuClosestTo:myLocation];
    CGPoint menuPoint = CGPointMake(menuPoints[idx], self.contentOffset.y);
    NSLog(@"    Dragging Ended at: %3.0f, %3.0f --> %3.0f, %3.0f",
         myLocation.x, myLocation.y, menuPoint.x, menuPoint.y);
    [self setContentOffset:menuPoint animated:YES];
}

I should note that this is in the simulator. I can't try it on the actual phone yet, since I haven't spent the money on the dev program yet (waiting until I have the app nearly ready to publish in case I run out of steam :).

Could this be a simulator problem? Has anybody seen something similar? Oh, yeah, I should ask: am I doing something wrong? ;)

Follow Up: I think the problem is that the deceleration animation is conflicting with my -(void) setContentOffset:animated: call. Both animations continue running and the view displays whichever wins, but the internal state is based correctly on setContentOffset. I thought setContentOffset turned off the existing animation. Does it, and, if not, how can I turn it off?

like image 514
Travis Jensen Avatar asked Mar 26 '11 23:03

Travis Jensen


1 Answers

Try using - (void)scrollRectToVisible:(CGRect)rect animated:(BOOL)animated (docs) instead of setting contentOffset.
Otherwise I can suggest checking out the paging property of UIScrollView, though it might be too limited to do what you want.

like image 72
unexpectedvalue Avatar answered Nov 15 '22 05:11

unexpectedvalue