Dragging UIView under finger

Parad0x13 picture Parad0x13 · Feb 12, 2011 · Viewed 23.7k times · Source

I want to tap on a UIView and drag and have that view follow my finger, simple enough. But the easiest way of doing this is by setting the objects center to where the tap happened (Which is not what I want), I want it to move as if you grabbed the object wherever you tapped it.

There was a very useful way of doing this and it was reference in one of the iTunes U videos. The script didn't use deltaX, deltaY for dragging the image underneath where you tapped on it instead of having it center underneath your finger but I can't remember what that code was!

Does anyone have a reference to this code? Or perhaps have an efficient way of moving UIViews under a finger without having the uiview.center = tap.center concept?

Answer

binary_falcon picture binary_falcon · Jul 3, 2012

The following code is an example of a simple gesture recognizer that will allow panel / view movement. Instead of modifying the center, you're modifying the origin point [basically by setting a new frame for the target view].

You can optimize this in your situation so you're not having to drill down into the gesture.view... etc

-(void)dragging:(UIPanGestureRecognizer *)gesture
{
    if(gesture.state == UIGestureRecognizerStateBegan)
    {
        //NSLog(@"Received a pan gesture");
        self.panCoord = [gesture locationInView:gesture.view];


    }
    CGPoint newCoord = [gesture locationInView:gesture.view];
    float dX = newCoord.x-panCoord.x;
    float dY = newCoord.y-panCoord.y;

gesture.view.frame = CGRectMake(gesture.view.frame.origin.x+dX, gesture.view.frame.origin.y+dY, gesture.view.frame.size.width, gesture.view.frame.size.height);
 }

Swift 4:

@objc func handleTap(_ sender: UIPanGestureRecognizer) {
        if(sender.state == .began) {
            self.panCoord = sender.location(in: sender.view)
        }

        let newCoord: CGPoint = sender.location(in: sender.view)

        let dX = newCoord.x - panCoord.x
        let dY = newCoord.y - panCoord.y

        sender.view?.frame = CGRect(x: (sender.view?.frame.origin.x)!+dX, y: (sender.view?.frame.origin.y)!+dY, width: (sender.view?.frame.size.width)!, height: (sender.view?.frame.size.height)!)
    }