Thursday, June 25, 2015

UIPanGestureRecognizer - Moving a ball(UIImage) with the pan gesture programmatically

Update: July 8, 2017 (Swift 3.1 + Xcode 8.3.3)
Update: July 18, 2016 (Swift 2.2 + Xcode 7.3.1)
Original Post: June 25, 2015

1. Add an image file named ball.png to the project. 

2. Modify your ViewController.swift as below by enabling either Method 1 or Method 2.

Update: July 8, 2017 (Swift 3.1 + Xcode 8.3.3)


import UIKit

class ViewController: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        let myImageView = UIImageView(image: UIImage(named: "ball.png"))
        myImageView.frame = CGRect(x: 100, y: 100, width: 50, height: 50)
        
        myImageView.isUserInteractionEnabled = true
        //Must be enabled for tap events
        
        view.addSubview(myImageView)
        //Add an image programmatically
        
        let myPanGestureRecognizer = UIPanGestureRecognizer(target: self, action: #selector(myPanAction)//Update: July 18, 2016 for Xcode 7.3.1(Swift 2.2)
        
        myPanGestureRecognizer.minimumNumberOfTouches = 1
        myPanGestureRecognizer.maximumNumberOfTouches = 1
        
        myImageView.addGestureRecognizer(myPanGestureRecognizer)
    }
    
    //Method 1:
    /*func myPanAction(recognizer: UIPanGestureRecognizer) {
        let translation = recognizer.translation(in: self.view)
            if let myView = recognizer.view {
            myView.center = CGPoint(x: myView.center.x + translation.x, y: myView.center.y + translation.y)
        }
            recognizer.setTranslation(CGPoint(x: 0, y: 0), in: self.view)
    }*/
    
    //Method 2:
    func myPanAction(recognizer: UIPanGestureRecognizer) {
        if ((recognizer.state != UIGestureRecognizerState.ended&&
            (recognizer.state != UIGestureRecognizerState.failed)) {
            recognizer.view?.center = recognizer.location(in: recognizer.view?.superview)
        }
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }

}

Update: July 18, 2016 (Swift 2.2 + Xcode 7.3.1)

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        
        let myImageView = UIImageView(image: UIImage(named: "ball.png"))
        myImageView.frame = CGRect(x: 100, y: 100, width: 50, height: 50)
        
        myImageView.userInteractionEnabled = true
        //Must be enabled for tap events
        
        view.addSubview(myImageView)
        //Add an image programmatically
        
        let myPanGestureRecognizer = UIPanGestureRecognizer(target: self, action: #selector(myPanAction)) //Update: July 18, 2016 for Xcode 7.3.1(Swift 2.2)
        
        myPanGestureRecognizer.minimumNumberOfTouches = 1
        myPanGestureRecognizer.maximumNumberOfTouches = 1
        
        myImageView.addGestureRecognizer(myPanGestureRecognizer)
    }
    
    //Method 1:
    /*func myPanAction(recognizer: UIPanGestureRecognizer) {
        let translation = recognizer.translationInView(self.view)
        if let myView = recognizer.view {
            myView.center = CGPoint(x: myView.center.x + translation.x, y: myView.center.y + translation.y)
        }
        recognizer.setTranslation(CGPointZero, inView: self.view)
    } */
    
    //Method 2:
    func myPanAction(recognizer: UIPanGestureRecognizer) {
        if ((recognizer.state != UIGestureRecognizerState.Ended) &&
        (recognizer.state != UIGestureRecognizerState.Failed)) {
            recognizer.view?.center = recognizer.locationInView(recognizer.view?.superview)
        }
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
}

Note: you may enable either Method 1 or Method 2.

3. The result:


5 comments:

  1. Thank you, this was probably the most helpful post related to Pan gestures I've found so far. Very concise and easy to use.

    ReplyDelete
    Replies
    1. Thanks for letting me know that this post is helpful to you. :)

      I've just updated this post to Xcode 7.3.1 and Swift 2.2.

      Delete
  2. Thank you so much for the information and clean code.

    ReplyDelete
  3. Hi
    Do you know I validate the position? I don't want to drag beyond certain bounds.

    ReplyDelete
  4. You're great. This worked perfectly.

    ReplyDelete