views:

350

answers:

1

I am trying to drag and drop UIViews within a UIScrollView. I'd like the UIScrollView to scroll if I drag a UIView so that it intersects the top or bottom of the ScrollView. If it touches the top, it should scroll up. If it touches the bottom, it should scroll down. Once the UIView is moved such that it is no longer intersecting the top or bottom, the scrolling should stop.

The first approach I tried was to start an NSTimer whenever I detected that the UIView intersected with the top or bottom of the scrollview. The timer would scroll the UIScrollView bit by bit until it was invalidated. This resulted in very jerky scrolling, since there is no way to predict when the timers will fire.

My current approach is to simply scroll all the way to the top or bottom of the ScrollView, like this:

[UIView beginAnimations:nil context:NULL];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationDuration:1.0];
[self.parentScrollview setContentOffset:newOffset animated:NO];
[UIView commitAnimations];

In order to stop scrolling, I try to determine the position of the touch in the touchesMoved: delegate, and use that to calculate the contentOffset to use for the scrollView.

The problem is, when I try to get the location in the view via [[touches anyObject] locationInView:self], I get the final end location, rather than the current location. I'm guessing that's because the contentOffset on the scrollView is set immediately.

Is there a way to get the actual location of a touch in a situation like this? Or any other way to set the contentOffset when I interrupt the scrolling animation?

A: 

This may be late, but you may try interrupting the old animation with a new animation including this statement:

    [UIView setAnimationBeginsFromCurrentState:YES];

You could make the new animation very short or zero duration, and then set a delegate and setAnimationDidStopSelector to get the final contentOffset value.

sehugg