How to get the touch coordinates from a valueChang

2019-04-21 08:34发布

问题:

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:

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.

回答1:

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)"
}


回答2:

Without seeing the rest of your code, it looks like you might need:

 let location = sender.convertPoint(CGPointZero, toView: myCustomControl)


回答3:

  1. Comment @UIApplicationMain line in AppDelegate
  2. Create new file with name main.swift and add this code in that file

    import UIKit
    import Foundation
    UIApplicationMain(Process.argc, Process.unsafeArgv, NSStringFromClass(AppClass), NSStringFromClass(AppDelegate))
    
  3. Create New class with name "AppClass" and subclass of UIApplication

  4. Write following code in that method import UIKit

    class AppClass: UIApplication {
        override func sendEvent(event: UIEvent)
        {
            super.sendEvent(event)
            print("send event") // this is an example
            // ... dispatch the message...
         }   
    }
    
  5. Here, in sendEvent method, you will get all the events happening in application(all screens), all touch events, so here you can use this UIEvent and perform any task if you want