I am developing a paint feature with a main canvas view and a floating toolbar above it. In my CanvasView I have:
final class CanvasView: UIView {
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
guard let touch = touches.first else { return }
let currentPoint = touch.location(in: self)
print("touch began \(currentPoint)")
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
guard let touch = touches.first else { return }
let currentPoint = touch.location(in: self)
print("touch move \(currentPoint)")
}
}
I add this to a view controller along with a toolbar:
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let canvasView = CanvasView()
canvasView.backgroundColor = .white
view.addSubview(canvasView)
canvasView.snp.makeConstraints { make in
make.edges.equalToSuperview()
}
let toolbarView = UIView()
toolbarView.backgroundColor = .black.withAlphaComponent(0.7)
view.addSubview(toolbarView)
toolbarView.snp.makeConstraints { make in
make.leading.trailing.bottom.equalToSuperview()
make.height.equalTo(200.0)
}
}
}
This looks like the following:
When I start dragging my finger around the canvas the touchesBegan and touchesMoved events are logged as follows. However if I move into the toolbar region touchesMoved is still logged. Note that I cannot trigger touchesBegan here.
I guess it's logical that touchesBegan won't fire since the canvas is obscured by the toolbar.
How would I go about stopping touchesMoved being triggered when dragging from the canvas into the toolbar area?

One option...
Use a closure so your
CanvasViewcan get the frame of thetoolbarViewand not execute any code if the touch point is inside that frame.So, change your
CanvasViewto this:and set the closure inside
viewDidLoadin your controller:Note that when we get the toolbar frame, we convert the rect to the coordinate space of the canvas view.
We want to do that because if the canvas view does not cover the entire view the coordinates will not be aligned.
Try this controller example to see -- it insets the canvas view so it's not "full screen" and it puts the toolbar view as a smaller rect not aligned with the full view:
It will look like this:
If your beginning touch is on the white canvas view, the
touchesMovedwill begin tracking (printing the touch location). As you drag the touch around, if it enters the gray rect (the toolbar view) it will stop printing the coordinates... but will resume as you drag the touch back to the white area.