Get The Start Point and End Point of The UIpangesturerecognizer in Swift

Get the start point and end point of the UIPanGestureRecognizer in Swift

For your case, you might want to include the code inside my function into your IBAction for the panGesture. Here I've created a view, but otherwise you would just be referring to self.view instead of view.

var view = UIView()

func panGestureMoveAround(gesture: UIPanGestureRecognizer) {

var locationOfBeganTap: CGPoint

var locationOfEndTap: CGPoint

if gesture.state == UIGestureRecognizerState.Began {

locationOfBeganTap = gesture.locationInView(view)

} else if gesture.state == UIGestureRecognizerState.Ended {

locationOfEndTap = gesture.locationInView(view)
}

}

How do I capture the point initially tapped in a UIPanGestureRecognizer?

Late to the party, but I notice that nothing above actually answers the question, and there is in fact a way to do this. You must subclass UIPanGestureRecognizer and include:

#import <UIKit/UIGestureRecognizerSubclass.h>

either in the Objective-C file in which you write the class or in your Swift bridging header. This will allow you to override the touchesBegan:withEvent method as follows:

class SomeCoolPanGestureRecognizer: UIPanGestureRecognizer {
private var initialTouchLocation: CGPoint!

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent) {
super.touchesBegan(touches, withEvent: event)
initialTouchLocation = touches.first!.locationInView(view)
}
}

Then your property initialTouchLocation will contain the information you seek. Of course in my example I make the assumption that the first touch in the set of touches is the one of interest, which makes sense if you have a maximumNumberOfTouches of 1. You may want to use more sophistication in finding the touch of interest.

Edit: Swift 5


import UIKit.UIGestureRecognizerSubclass

class InitialPanGestureRecognizer: UIPanGestureRecognizer {
private var initialTouchLocation: CGPoint!

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent) {
super.touchesBegan(touches, with: event)
initialTouchLocation = touches.first!.location(in: view)
}
}

How to access the initial point of a Pan Gesture in it's .Ended state

The way you are doing this doesn’t work. Instead, calculate it all at the end:

func handleTestViewTap (panRecognizer: UIPanGestureRecognizer){

if panRecognizer.state == UIGestureRecognizerState.Ended {
print("locationOfBeganTap -> (.\(touch.locationInView(view).x - touch.translationInView(view).x), .\(touch.locationInView(view).y - touch.translationInView(view).y))")
print("location in ENDED State -> .\(touch.locationInView(view))")
}
}

Draw a rectangle the starting point and follow my movement to end the gesture in Swift

You need to create a subclass of UIView call it something like RectView and like this:

@IBDesignable
class RectView: UIView {
@IBInspectable var startPoint:CGPoint?{
didSet{
self.setNeedsDisplay()
}
}

@IBInspectable var endPoint:CGPoint?{
didSet{
self.setNeedsDisplay()
}
}

override func drawRect(rect: CGRect) {
if (startPoint != nil && endPoint != nil){
let path:UIBezierPath = UIBezierPath(rect: CGRectMake(min(startPoint!.x, endPoint!.x),
min(startPoint!.y, endPoint!.y),
fabs(startPoint!.x - endPoint!.x),
fabs(startPoint!.y - endPoint!.y)))
path.stroke()
}
}

}

Then in your view controller you can say something like:

@IBAction func panGestureMoveAround(sender: UIPanGestureRecognizer) {
var locationOfBeganTap: CGPoint

var locationOfEndTap: CGPoint

if sender.state == UIGestureRecognizerState.Began {
locationOfBeganTap = sender.locationInView(rectView)
rectView.startPoint = locationOfBeganTap
rectView.endPoint = locationOfBeganTap

} else if sender.state == UIGestureRecognizerState.Ended {
locationOfEndTap = sender.locationInView(rectView)
rectView.endPoint = sender.locationInView(rectView)
} else{
rectView.endPoint = sender.locationInView(rectView)
}
}

Swift 5 version

class RectView: UIView {
var startPoint: CGPoint? {
didSet {
setNeedsDisplay()
}
}

var endPoint: CGPoint? {
didSet {
setNeedsDisplay()
}
}

override func draw(_ rect: CGRect) {
guard let startPoint = startPoint, let endPoint = endPoint else {
return
}

let path = UIBezierPath(
rect: CGRect(
x: min(startPoint.x, endPoint.x),
y: min(startPoint.y, endPoint.y),
width: abs(startPoint.x - endPoint.x),
height: abs(startPoint.y - endPoint.y)
)
)
path.stroke()
}
}
@objc func panGestureMoveAround(_ sender: UIPanGestureRecognizer) {
var locationOfBeganTap: CGPoint

switch sender.state {
case .began:
locationOfBeganTap = sender.location(in: rectView)
rectView.startPoint = locationOfBeganTap
rectView.endPoint = locationOfBeganTap
case .changed:
rectView.endPoint = sender.location(in: rectView)
case .ended:
rectView.endPoint = sender.location(in: rectView)
default:
break
}
}

How to get current touch point and previous touch point in UIPanGestureRecognizer method?

You can use this:

CGPoint currentlocation = [recognizer locationInView:self.view];

Store previous location by setting current location if not found and adding current location everytime.

previousLocation = [recognizer locationInView:self.view]; 

UIPanGestureRecognizer get the length between start and stop

The problem is that handlePanRecognizer() is called every time the gesture is updated, so when the gesture ends, you don't have the startLocation because it was set in another call of the handler method.

You should store last location as an optional property:

var startPanLocation: CGPoint?

Now set it in .began case and use it to calculate the distance in .ended case:

func handlePanRecognizer(panRecognizer: UIPanGestureRecognizer) {
let currentLocation = panRecognizer.location(in: self.newEffectView)

switch panRecognizer.state {
case .began:
startPanLocation = currentLocation
case .ended:
let dx = currentLocation.x - startPanLocation.x;
let dy = currentLocation.y - startPanLocation.y;
let distance = sqrt(dx*dx + dy*dy );
startPanLocation = nil
default: break
}
}

Btw, you cannot use the variable if it was defined but not initialized:

let startLocation : CGPoint      //defined
let startLocation = CGPoint.zero //initialized

Get original touch location from UIPanGestureRecognizer

You should be able to set the delegate for the gesture recogniser and implement

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch

to get the initial touch.

Detecting Pan Gesture End

Pan gesture end event can be detected by checking its state with UIGestureRecognizerStateEnded.

Check with the below code .

-(void) panAnim:(UIPanGestureRecognizer*) gestureRecognizer
{
if(gestureRecognizer.state == UIGestureRecognizerStateEnded)
{
//All fingers are lifted.
}
}

From Apple documentation

A panning gesture is continuous. It
begins (UIGestureRecognizerStateBegan)
when the minimum number of fingers
allowed (minimumNumberOfTouches) has
moved enough to be considered a pan.
It changes
(UIGestureRecognizerStateChanged) when
a finger moves while at least the
minimum number of fingers are pressed
down. It ends
(UIGestureRecognizerStateEnded) when
all fingers are lifted.

Read more about UIPanGestureRecognizer



Related Topics



Leave a reply



Submit