mirror of
https://github.com/dscyrescotti/Memola.git
synced 2026-04-25 10:08:34 +02:00
feat: resolve pinch gesture conflict with responder touches
This commit is contained in:
@@ -32,6 +32,13 @@ final class Canvas: NSObject, ObservableObject, Identifiable, Codable, GraphicCo
|
|||||||
@Published var state: State = .initial
|
@Published var state: State = .initial
|
||||||
lazy var didUpdate = PassthroughSubject<Void, Never>()
|
lazy var didUpdate = PassthroughSubject<Void, Never>()
|
||||||
|
|
||||||
|
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)) {
|
init(size: CGSize = .init(width: 4_000, height: 4_000)) {
|
||||||
self.size = size
|
self.size = size
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,8 @@ class Stroke: Codable {
|
|||||||
var vertexBuffer: MTLBuffer?
|
var vertexBuffer: MTLBuffer?
|
||||||
var vertexCount: Int = 0
|
var vertexCount: Int = 0
|
||||||
|
|
||||||
|
let createdAt: Date = Date()
|
||||||
|
|
||||||
var texture: MTLTexture?
|
var texture: MTLTexture?
|
||||||
|
|
||||||
var isEmpty: Bool {
|
var isEmpty: Bool {
|
||||||
|
|||||||
@@ -40,7 +40,6 @@ class CanvasViewController: UIViewController {
|
|||||||
override func viewDidLoad() {
|
override func viewDidLoad() {
|
||||||
super.viewDidLoad()
|
super.viewDidLoad()
|
||||||
configureViews()
|
configureViews()
|
||||||
configureGestures()
|
|
||||||
configureListeners()
|
configureListeners()
|
||||||
|
|
||||||
loadMemo()
|
loadMemo()
|
||||||
@@ -84,8 +83,6 @@ extension CanvasViewController {
|
|||||||
scrollView.showsHorizontalScrollIndicator = true
|
scrollView.showsHorizontalScrollIndicator = true
|
||||||
scrollView.delegate = self
|
scrollView.delegate = self
|
||||||
scrollView.backgroundColor = .clear
|
scrollView.backgroundColor = .clear
|
||||||
// scrollView.pinchGestureRecognizer?.cancelsTouchesInView = true
|
|
||||||
// scrollView.pinchGestureRecognizer?.delaysTouchesEnded = true
|
|
||||||
|
|
||||||
scrollView.translatesAutoresizingMaskIntoConstraints = false
|
scrollView.translatesAutoresizingMaskIntoConstraints = false
|
||||||
view.addSubview(scrollView)
|
view.addSubview(scrollView)
|
||||||
@@ -99,8 +96,6 @@ extension CanvasViewController {
|
|||||||
scrollView.addSubview(drawingView)
|
scrollView.addSubview(drawingView)
|
||||||
drawingView.backgroundColor = .clear
|
drawingView.backgroundColor = .clear
|
||||||
drawingView.isUserInteractionEnabled = false
|
drawingView.isUserInteractionEnabled = false
|
||||||
drawingView.isMultipleTouchEnabled = true
|
|
||||||
drawingView.isExclusiveTouch = true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func resizeDocumentView(to newSize: CGSize? = nil) {
|
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 {
|
extension CanvasViewController: UIScrollViewDelegate {
|
||||||
func viewForZooming(in scrollView: UIScrollView) -> UIView? {
|
func viewForZooming(in scrollView: UIScrollView) -> UIView? {
|
||||||
drawingView
|
drawingView
|
||||||
@@ -277,6 +233,7 @@ extension CanvasViewController: UIScrollViewDelegate {
|
|||||||
extension CanvasViewController {
|
extension CanvasViewController {
|
||||||
func magnificationStarted() {
|
func magnificationStarted() {
|
||||||
guard !renderer.updatesViewPort else { return }
|
guard !renderer.updatesViewPort else { return }
|
||||||
|
drawingView.touchCancelled()
|
||||||
canvas.updateClipBounds(scrollView, on: drawingView)
|
canvas.updateClipBounds(scrollView, on: drawingView)
|
||||||
drawingView.disableUserInteraction()
|
drawingView.disableUserInteraction()
|
||||||
renderer.updatesViewPort = true
|
renderer.updatesViewPort = true
|
||||||
|
|||||||
@@ -17,8 +17,6 @@ class DrawingView: UIView {
|
|||||||
|
|
||||||
var ratio: CGFloat { canvas.size.width / bounds.width }
|
var ratio: CGFloat { canvas.size.width / bounds.width }
|
||||||
|
|
||||||
var beganTouches: Set<UITouch> = []
|
|
||||||
|
|
||||||
private var disablesUserInteraction: Bool = false
|
private var disablesUserInteraction: Bool = false
|
||||||
|
|
||||||
required init(tool: Tool, canvas: Canvas, history: History) {
|
required init(tool: Tool, canvas: Canvas, history: History) {
|
||||||
@@ -37,69 +35,36 @@ class DrawingView: UIView {
|
|||||||
renderView.drawableSize = size.multiply(by: 2.5)
|
renderView.drawableSize = size.multiply(by: 2.5)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
|
||||||
|
!canvas.hasValidStroke
|
||||||
|
}
|
||||||
|
|
||||||
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
|
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
|
||||||
print("Touch Began - \(touches.count) & \(event?.allTouches?.count ?? -1)")
|
|
||||||
super.touchesBegan(touches, with: event)
|
super.touchesBegan(touches, with: event)
|
||||||
for touch in touches {
|
guard let touch = touches.first else { return }
|
||||||
beganTouches.insert(touch)
|
let point = touch.location(in: self)
|
||||||
}
|
touchBegan(at: point)
|
||||||
}
|
}
|
||||||
|
|
||||||
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
|
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
|
||||||
print("Touch Moved - \(beganTouches.count) & \(event?.allTouches?.count ?? -1)")
|
|
||||||
super.touchesMoved(touches, with: event)
|
super.touchesMoved(touches, with: event)
|
||||||
validateTouch()
|
|
||||||
guard let touch = touches.first else { return }
|
guard let touch = touches.first else { return }
|
||||||
let point = touch.location(in: self)
|
let point = touch.location(in: self)
|
||||||
touchMoved(to: point)
|
touchMoved(to: point)
|
||||||
}
|
}
|
||||||
|
|
||||||
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
|
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
|
||||||
print("Touch Ended - \(beganTouches.count)")
|
|
||||||
super.touchesEnded(touches, with: event)
|
super.touchesEnded(touches, with: event)
|
||||||
validateTouch()
|
|
||||||
guard let touch = touches.first else { return }
|
guard let touch = touches.first else { return }
|
||||||
let point = touch.location(in: self)
|
let point = touch.location(in: self)
|
||||||
touchEnded(at: point)
|
touchEnded(at: point)
|
||||||
}
|
}
|
||||||
|
|
||||||
override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) {
|
override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) {
|
||||||
print("Touch Cancelled - \(beganTouches.count)")
|
|
||||||
super.touchesCancelled(touches, with: event)
|
super.touchesCancelled(touches, with: event)
|
||||||
touchCancelled()
|
guard let touch = touches.first else { return }
|
||||||
}
|
let point = touch.location(in: self)
|
||||||
|
touchEnded(at: point)
|
||||||
// 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()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func touchBegan(at point: CGPoint) {
|
func touchBegan(at point: CGPoint) {
|
||||||
@@ -113,14 +78,15 @@ class DrawingView: UIView {
|
|||||||
func touchMoved(to point: CGPoint) {
|
func touchMoved(to point: CGPoint) {
|
||||||
guard !disablesUserInteraction else { return }
|
guard !disablesUserInteraction else { return }
|
||||||
canvas.moveTouch(to: point.muliply(by: ratio))
|
canvas.moveTouch(to: point.muliply(by: ratio))
|
||||||
renderView.draw()
|
if canvas.hasValidStroke {
|
||||||
|
renderView.draw()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func touchEnded(at point: CGPoint) {
|
func touchEnded(at point: CGPoint) {
|
||||||
guard !disablesUserInteraction else { return }
|
guard !disablesUserInteraction else { return }
|
||||||
canvas.endTouch(at: point.muliply(by: ratio))
|
canvas.endTouch(at: point.muliply(by: ratio))
|
||||||
renderView.draw()
|
renderView.draw()
|
||||||
beganTouches.removeAll()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func touchCancelled() {
|
func touchCancelled() {
|
||||||
@@ -129,7 +95,6 @@ class DrawingView: UIView {
|
|||||||
renderView.draw()
|
renderView.draw()
|
||||||
history.restoreUndo()
|
history.restoreUndo()
|
||||||
}
|
}
|
||||||
beganTouches.removeAll()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func disableUserInteraction() {
|
func disableUserInteraction() {
|
||||||
|
|||||||
Reference in New Issue
Block a user