Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get the touch coordinates from a valueChanged event in Swift

Background

I've previously learned how to use a Gesture Recognizer or continueTrackingWithTouch to get continuous updates of the current touch location and to then use those to do something like this:

enter image description here

Now, however, I would like to learn how to do the same thing using targets. I can already get the touch down and touch up events by using TouchDown and TouchUpInside, but I don't know how to get the continuous updates. I assumed that it would be using the ValueChanged event, but so far that isn't working.

This is what I have tried:

ViewController.swift

import UIKit
class ViewController: UIViewController {

    @IBOutlet weak var myCustomControl: MyCustomControl!
    @IBOutlet weak var trackingBeganLabel: UILabel!
    @IBOutlet weak var trackingEndedLabel: UILabel!
    @IBOutlet weak var xLabel: UILabel!
    @IBOutlet weak var yLabel: UILabel!

    override func viewDidLoad() {
        super.viewDidLoad()

        // these work
        myCustomControl.addTarget(self, action: "myTouchDown", forControlEvents: UIControlEvents.TouchDown)
        myCustomControl.addTarget(self, action: "myTouchUpInside", forControlEvents: UIControlEvents.TouchUpInside)

        // this doesn't work
        myCustomControl.addTarget(self, action: "myValueChangedEvent:",
            forControlEvents: UIControlEvents.ValueChanged)
    }

    // this works
    func myTouchDown() {
        trackingBeganLabel.text = "Touched down"
    }

    // this works
    func myTouchUpInside() {
        trackingEndedLabel.text = "Touch up inside"
    }

    // this doesn't work, function never gets called
    func myValueChangedEvent(sender: UIControl) { 
        let location = sender.convertPoint(CGPointZero, toView: myCustomControl) 
        xLabel.text = "x: \(location.x)"
        yLabel.text = "y: \(location.y)"
    }
}

MyCustomControl.swift

import UIKit
class MyCustomControl: UIControl {
    // currently empty. Do I need to add something here?
}

Notes

  • Changed the code after getting @CaseyWagner's answer. The compiler doesn't throw an error anymore but UIControlEvents.ValueChanged never gets fired.
  • This question is my attempt to have a complete answer for the Method 1: Adding a Target section of this answer.
like image 685
Suragch Avatar asked Jan 13 '16 09:01

Suragch


1 Answers

Use UIControlEvents.TouchDragInside instead of UIControlEvents.ValueChanged (also notice that action method receives two arguments):

myCustomControl.addTarget(self, action: "didDragInsideControl:withEvent:",
        forControlEvents: UIControlEvents.TouchDragInside)

The handler function looks like this:

func didDragInsideControl(control: MyCustomControl, withEvent event: UIEvent) {
    let touch = event.touchesForView(control)!.first!
    let location = touch.locationInView(control)
    xLabel.text = "x: \(location.x)"
    yLabel.text = "y: \(location.y)"
}
like image 57
Konstantine Kalbazov Avatar answered Sep 28 '22 07:09

Konstantine Kalbazov