How do I detect which way the user is swiping?

105 Views Asked by At

I'm using the code below so that the user can swipe a UIImageView to whatever direction they want. I need to detect which way the user is swiping. If it's swiped for example to the left it needs to println "Swiped left!" Is there any way to do this?

  let ThrowingThreshold: CGFloat = 1000
  let ThrowingVelocityPadding: CGFloat = 35

  @IBOutlet weak var imageView: UIImageView!
  @IBOutlet weak var redSquare: UIView!
  @IBOutlet weak var blueSquare: UIView!

  private var originalBounds = CGRect.zeroRect
  private var originalCenter = CGPoint.zeroPoint

  private var animator: UIDynamicAnimator!
  private var attachmentBehavior: UIAttachmentBehavior!
  private var pushBehavior: UIPushBehavior!
  private var itemBehavior: UIDynamicItemBehavior!

    func resetDemo() {
        animator.removeAllBehaviors()

        UIView.animateWithDuration(0.45) {
            self.imageView.bounds = self.originalBounds
            self.imageView.center = self.originalCenter
            self.imageView.transform = CGAffineTransformIdentity
        }
    }
@IBAction func handleAttachmentGesture(sender: UIPanGestureRecognizer) {
    let location = sender.locationInView(self.view)
    let boxLocation = sender.locationInView(self.imageView)

    switch sender.state {
    case .Began:
      println("Your touch start position is \(location)")
      println("Start location in image is \(boxLocation)")

      // 1
      animator.removeAllBehaviors()

      // 2
      let centerOffset = UIOffset(horizontal: boxLocation.x - imageView.bounds.midX,
        vertical: boxLocation.y - imageView.bounds.midY)
      attachmentBehavior = UIAttachmentBehavior(item: imageView,
        offsetFromCenter: centerOffset, attachedToAnchor: location)

      // 3
      redSquare.center = attachmentBehavior.anchorPoint
      blueSquare.center = location

      // 4
      animator.addBehavior(attachmentBehavior)

    case .Ended:
      println("Your touch end position is \(location)")
      println("End location in image is \(boxLocation)")

      animator.removeAllBehaviors()

      // 1
      let velocity = sender.velocityInView(view)
      let magnitude = sqrt((velocity.x * velocity.x) + (velocity.y * velocity.y))

      if magnitude > ThrowingThreshold {
        // 2
        let pushBehavior = UIPushBehavior(items: [imageView], mode: .Instantaneous)
        pushBehavior.pushDirection = CGVector(dx: velocity.x / 10, dy: velocity.y / 10)
        pushBehavior.magnitude = magnitude / ThrowingVelocityPadding

        self.pushBehavior = pushBehavior
        animator.addBehavior(pushBehavior)

        // 3
        let angle = Int(arc4random_uniform(20)) - 10

        itemBehavior = UIDynamicItemBehavior(items: [imageView])
        itemBehavior.friction = 0.2
        itemBehavior.allowsRotation = true
        itemBehavior.addAngularVelocity(CGFloat(angle), forItem: imageView)
        animator.addBehavior(itemBehavior)

        // 4
        let timeOffset = Int64(0.4 * Double(NSEC_PER_SEC))
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, timeOffset), dispatch_get_main_queue()) {
            self.resetDemo()
        }
      } else {
        resetDemo()
        }

        default:
            attachmentBehavior.anchorPoint = sender.locationInView(view)
            redSquare.center = attachmentBehavior.anchorPoint
        }

override func viewDidLoad() {
    super.viewDidLoad()
    animator = UIDynamicAnimator(referenceView: view)
    originalBounds = imageView.bounds
    originalCenter = imageView.center
1

There are 1 best solutions below

6
On

You can use the translationInView function of the gesture to get a CGPoint representing the movement of the gesture since it started (or since you last reset it). This tells you the relative movement in the x and y directions.

If you're interested in the overall movement then you can just read this and use the sign of the x and y values to determine the direction moved.

If you're interested in the instantaneous direction of movement then you can use the same approach, but after reading the translation you can use setTranslation:inView: to reset to CGPointZero. In this way the translation provided in the next callback is the delta movement.