views:

2075

answers:

1

I am trying to figure out how can you drag an image while constraining its movement along a certain path.

I tried several tricks including animation along a path, but couldn't get the animation to play and pause and play backwards - so that seems out of the question.

Any ideas ? anyone ?

+2  A: 

What you're basically trying to do is match finger movement to a 'translation' transition.

As the user touches down and starts to move their finger you want to use the current touch point value to create a translation transform which you apply to your UIImageView. Here's how you would do it:

  1. On touch down, save the imageview's starting x,y position.

  2. On move, calculate the delta from old point to new one. This is where you can clamp the values. So you can ignore, say, the y change and only use the x deltas. This means that the image will only move left to right. If you ignore the x and use y, then it only moves up and down.

  3. Once you have the 'new' calculated/clamped x,y values, use it to create a new transform using CGAffineTransformMakeTranslation(x, y). Assign this transform to the UIImageView. The image moves to that place.

  4. Once the finger lifts, figure out the delta from the original starting x,y, point and the lift-off point, then adjust the ImageView's bounds and reset the transform to CGAffineTransformIdentity. This doesn't move the object, but it sets it so subsequent accesses to the ImageView use the actual position and don't have to keep adjusting for transforms.

Moving along on a grid is easy too. Just round out the x,y values in step 2 so they're a multiple of the grid size (i.e. round out to every 10 pixel) before you pass it on to make the translation transform.

If you want to make it extra smooth, surround the code where you assign the transition with UIView animation blocks. Mess around with the easing and timing settings. The image should drag behind a bit but smoothly 'rubber-band' from one touch point to the next.

Ramin
Yup, sounds good, though you might want to just set `position` instead of messing w/ the transform.
Andrew Pouliot