From 0202678d8d7e06220c0a9a6f76022282f5847051 Mon Sep 17 00:00:00 2001 From: dscyrescotti Date: Mon, 6 May 2024 21:02:23 +0700 Subject: [PATCH] feat: resolve pinch gesture conflict with responder touches --- Memola/Canvas/Core/Canvas.swift | 7 +++ Memola/Canvas/Geometries/Stroke/Stroke.swift | 2 + .../ViewController/CanvasViewController.swift | 45 +------------- .../View/Bridge/Views/DrawingView.swift | 61 ++++--------------- 4 files changed, 23 insertions(+), 92 deletions(-) diff --git a/Memola/Canvas/Core/Canvas.swift b/Memola/Canvas/Core/Canvas.swift index 9c81794..f8d2381 100644 --- a/Memola/Canvas/Core/Canvas.swift +++ b/Memola/Canvas/Core/Canvas.swift @@ -32,6 +32,13 @@ final class Canvas: NSObject, ObservableObject, Identifiable, Codable, GraphicCo @Published var state: State = .initial lazy var didUpdate = PassthroughSubject() + var hasValidStroke: Bool { + if let currentStroke = graphicContext.currentStroke { + return Date.now.timeIntervalSince(currentStroke.createdAt) * 1000 > 80 + } + return false + } + init(size: CGSize = .init(width: 4_000, height: 4_000)) { self.size = size } diff --git a/Memola/Canvas/Geometries/Stroke/Stroke.swift b/Memola/Canvas/Geometries/Stroke/Stroke.swift index 6272536..31cd2e3 100644 --- a/Memola/Canvas/Geometries/Stroke/Stroke.swift +++ b/Memola/Canvas/Geometries/Stroke/Stroke.swift @@ -22,6 +22,8 @@ class Stroke: Codable { var vertexBuffer: MTLBuffer? var vertexCount: Int = 0 + let createdAt: Date = Date() + var texture: MTLTexture? var isEmpty: Bool { diff --git a/Memola/Canvas/View/Bridge/ViewController/CanvasViewController.swift b/Memola/Canvas/View/Bridge/ViewController/CanvasViewController.swift index 4f98fc2..5a3907a 100644 --- a/Memola/Canvas/View/Bridge/ViewController/CanvasViewController.swift +++ b/Memola/Canvas/View/Bridge/ViewController/CanvasViewController.swift @@ -40,7 +40,6 @@ class CanvasViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() configureViews() - configureGestures() configureListeners() loadMemo() @@ -84,8 +83,6 @@ extension CanvasViewController { scrollView.showsHorizontalScrollIndicator = true scrollView.delegate = self scrollView.backgroundColor = .clear -// scrollView.pinchGestureRecognizer?.cancelsTouchesInView = true -// scrollView.pinchGestureRecognizer?.delaysTouchesEnded = true scrollView.translatesAutoresizingMaskIntoConstraints = false view.addSubview(scrollView) @@ -99,8 +96,6 @@ extension CanvasViewController { scrollView.addSubview(drawingView) drawingView.backgroundColor = .clear drawingView.isUserInteractionEnabled = false - drawingView.isMultipleTouchEnabled = true - drawingView.isExclusiveTouch = true } func resizeDocumentView(to newSize: CGSize? = nil) { @@ -189,45 +184,6 @@ extension CanvasViewController: MTKViewDelegate { } } -extension CanvasViewController { - func configureGestures() { -// let drawingPanGesture = PanGestureRecognizer(target: self, action: #selector(recognizePanGesture)) -// drawingPanGesture.maximumNumberOfTouches = 1 -// drawingPanGesture.minimumNumberOfTouches = 1 -// drawingView.addGestureRecognizer(drawingPanGesture) - -// let drawingTapGesture = UITapGestureRecognizer(target: self, action: #selector(recognizeTapGesture)) -// drawingTapGesture.numberOfTapsRequired = 1 -// drawingView.addGestureRecognizer(drawingTapGesture) - } - -// @objc func recognizePanGesture(_ gesture: PanGestureRecognizer) { -// let point = gesture.location(in: drawingView) -// switch gesture.state { -// case .began: -// if let initialTouch = gesture.initialTouch { -// drawingView.touchBegan(on: initialTouch.location(in: drawingView)) -// } else { -// drawingView.touchBegan(on: point) -// } -// case .changed: -// drawingView.touchMoved(to: point) -// case .ended: -// drawingView.touchEnded(to: point) -// case .cancelled: -// drawingView.touchEnded(to: point) -// default: -// break -// } -// } - -// @objc func recognizeTapGesture(_ gesture: UITapGestureRecognizer) { -// let point = gesture.location(in: drawingView) -// drawingView.touchBegan(on: point) -// drawingView.touchEnded(to: point) -// } -} - extension CanvasViewController: UIScrollViewDelegate { func viewForZooming(in scrollView: UIScrollView) -> UIView? { drawingView @@ -277,6 +233,7 @@ extension CanvasViewController: UIScrollViewDelegate { extension CanvasViewController { func magnificationStarted() { guard !renderer.updatesViewPort else { return } + drawingView.touchCancelled() canvas.updateClipBounds(scrollView, on: drawingView) drawingView.disableUserInteraction() renderer.updatesViewPort = true diff --git a/Memola/Canvas/View/Bridge/Views/DrawingView.swift b/Memola/Canvas/View/Bridge/Views/DrawingView.swift index a34705d..20c263d 100644 --- a/Memola/Canvas/View/Bridge/Views/DrawingView.swift +++ b/Memola/Canvas/View/Bridge/Views/DrawingView.swift @@ -17,8 +17,6 @@ class DrawingView: UIView { var ratio: CGFloat { canvas.size.width / bounds.width } - var beganTouches: Set = [] - private var disablesUserInteraction: Bool = false required init(tool: Tool, canvas: Canvas, history: History) { @@ -37,69 +35,36 @@ class DrawingView: UIView { renderView.drawableSize = size.multiply(by: 2.5) } + override func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool { + !canvas.hasValidStroke + } + override func touchesBegan(_ touches: Set, with event: UIEvent?) { - print("Touch Began - \(touches.count) & \(event?.allTouches?.count ?? -1)") super.touchesBegan(touches, with: event) - for touch in touches { - beganTouches.insert(touch) - } + guard let touch = touches.first else { return } + let point = touch.location(in: self) + touchBegan(at: point) } override func touchesMoved(_ touches: Set, with event: UIEvent?) { - print("Touch Moved - \(beganTouches.count) & \(event?.allTouches?.count ?? -1)") super.touchesMoved(touches, with: event) - validateTouch() guard let touch = touches.first else { return } let point = touch.location(in: self) touchMoved(to: point) } override func touchesEnded(_ touches: Set, with event: UIEvent?) { - print("Touch Ended - \(beganTouches.count)") super.touchesEnded(touches, with: event) - validateTouch() guard let touch = touches.first else { return } let point = touch.location(in: self) touchEnded(at: point) } override func touchesCancelled(_ touches: Set, with event: UIEvent?) { - print("Touch Cancelled - \(beganTouches.count)") super.touchesCancelled(touches, with: event) - touchCancelled() - } - -// func didCreateNewStroke() -> Bool { -// switch beganTouches.count { -// case 0: -// return true -// case 1: -// if canvas.graphicContext.currentStroke == nil { -// guard let touch = beganTouches.first else { return false } -// let point = touch.location(in: self) -// touchBegan(at: point) -// beganTouches.removeAll() -// return true -// } else { -// touchCancelled() -// return false -// } -// default: -// return false -// } -// } - - func validateTouch() { - if beganTouches.count == 1 { - if canvas.graphicContext.currentStroke == nil { - guard let touch = beganTouches.first else { return } - let point = touch.location(in: self) - touchBegan(at: point) - beganTouches.removeAll() - } else { - touchCancelled() - } - } + guard let touch = touches.first else { return } + let point = touch.location(in: self) + touchEnded(at: point) } func touchBegan(at point: CGPoint) { @@ -113,14 +78,15 @@ class DrawingView: UIView { func touchMoved(to point: CGPoint) { guard !disablesUserInteraction else { return } canvas.moveTouch(to: point.muliply(by: ratio)) - renderView.draw() + if canvas.hasValidStroke { + renderView.draw() + } } func touchEnded(at point: CGPoint) { guard !disablesUserInteraction else { return } canvas.endTouch(at: point.muliply(by: ratio)) renderView.draw() - beganTouches.removeAll() } func touchCancelled() { @@ -129,7 +95,6 @@ class DrawingView: UIView { renderView.draw() history.restoreUndo() } - beganTouches.removeAll() } func disableUserInteraction() {