0

NOTE that I looked a lot everywhere but couldn't find a solution.

Using the Storyboard, I have a ViewController, with a View (UIView) and a Subview (PKCanvasView) where I want to use PencilKit to draw on the latter.

_

My objectives are:

  1. Draw only on this PKCanvasView

  2. Get the coordinates in real time of where I'm drawing on the PKCanvasView

My results:

  1. I can draw on the PKCanvasView only if I start from this view, and I can only draw within the frame of this PKCanvasView. That's good.

  2. I can only manage to get the coordinates of where I'm touching the screen IF I start the gesture on the UIView. BUT Not if I touch the PKCanvasView first.

My problem:

How do I get the coordinates of where I'm drawing on the PKCanvasView?

Below is my code:

import UIKit
import PencilKit

class ViewController: UIViewController {

    @IBOutlet weak var labelText: UILabel! //Label object to display the coordinates

    @IBOutlet weak var canvasView: PKCanvasView! //Subview to draw on

    override func viewDidAppear(_ animated: Bool) {
        canvasView.tool = PKInkingTool(.pen, color: .black, width: 10)
    }

    // MARK: FUNCTIONS //
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        touches.forEach { (touch) in
            updateGagues(with: touch)
        }
    }

    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
        touches.forEach { (touch) in
            updateGagues(with: touch)
        }
    }

    private func updateGagues(with touch: UITouch) {
        let location = touch.preciseLocation(in: view)
        labelText.text = location.debugDescription
    }
}

1 Answers1

6

I recently experienced the same problem of getting touch coordinates from my PKCanvasView. To do this, I created a subclass of PKCanvasView and overrode the touchesBegan function:

class Canvas: PKCanvasView {

  override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    touches.forEach { touch in
      print("touch location \(touch.location(in: self))")
    }
  }

}
oseph
  • 61
  • 1
  • 4
  • I haven’t tried this yet but presumably the canvas view needs the touch methods to actually do the drawing, if you override them, then wouldn’t all that functionality be lost? – johnbakers Nov 28 '20 at 14:10
  • 1
    Just add: super.touchesBegan(touches, with: event) before your own implementation, then the inherited functionality will be called as well. – Marian König Feb 08 '21 at 18:07