Fix tap gesture blocked by line brush drag gesture
The DragGesture with minimumDistance: 0 for line brush mode was consuming all touches, preventing tap detection for Object/Person/Wire tools. Fixed by: 1. Only attaching line brush gesture when in line brush mode 2. Added conditional .if() view modifier extension 3. Added debug logging to tap gesture to track gesture flow Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -8,6 +8,19 @@
|
|||||||
import SwiftUI
|
import SwiftUI
|
||||||
import UIKit
|
import UIKit
|
||||||
|
|
||||||
|
// MARK: - Conditional View Modifier
|
||||||
|
|
||||||
|
extension View {
|
||||||
|
@ViewBuilder
|
||||||
|
func `if`<Content: View>(_ condition: Bool, transform: (Self) -> Content) -> some View {
|
||||||
|
if condition {
|
||||||
|
transform(self)
|
||||||
|
} else {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct CanvasView: View {
|
struct CanvasView: View {
|
||||||
@Bindable var viewModel: EditorViewModel
|
@Bindable var viewModel: EditorViewModel
|
||||||
|
|
||||||
@@ -67,11 +80,14 @@ struct CanvasView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
.contentShape(Rectangle())
|
.contentShape(Rectangle())
|
||||||
.gesture(lineBrushGesture(in: geometry))
|
|
||||||
.gesture(tapGesture(in: geometry))
|
.gesture(tapGesture(in: geometry))
|
||||||
.gesture(magnificationGesture(in: geometry))
|
.gesture(magnificationGesture(in: geometry))
|
||||||
.simultaneousGesture(dragGesture(in: geometry))
|
.simultaneousGesture(dragGesture(in: geometry))
|
||||||
.simultaneousGesture(longPressGesture)
|
.simultaneousGesture(longPressGesture)
|
||||||
|
// Only attach line brush gesture when in line brush mode
|
||||||
|
.if(viewModel.selectedTool == .wire && viewModel.isLineBrushMode) { view in
|
||||||
|
view.gesture(lineBrushGesture(in: geometry))
|
||||||
|
}
|
||||||
.onTapGesture(count: 2) {
|
.onTapGesture(count: 2) {
|
||||||
doubleTapZoom()
|
doubleTapZoom()
|
||||||
}
|
}
|
||||||
@@ -127,16 +143,30 @@ struct CanvasView: View {
|
|||||||
private func tapGesture(in geometry: GeometryProxy) -> some Gesture {
|
private func tapGesture(in geometry: GeometryProxy) -> some Gesture {
|
||||||
SpatialTapGesture()
|
SpatialTapGesture()
|
||||||
.onEnded { value in
|
.onEnded { value in
|
||||||
guard !viewModel.isProcessing,
|
DebugLogger.action("CanvasView tap at \(value.location)")
|
||||||
!viewModel.showingMaskConfirmation,
|
DebugLogger.state("isProcessing: \(viewModel.isProcessing), showingMaskConfirmation: \(viewModel.showingMaskConfirmation), tool: \(viewModel.selectedTool)")
|
||||||
viewModel.selectedTool != .brush else { return }
|
|
||||||
|
guard !viewModel.isProcessing else {
|
||||||
|
DebugLogger.log("Tap ignored - isProcessing")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
guard !viewModel.showingMaskConfirmation else {
|
||||||
|
DebugLogger.log("Tap ignored - showingMaskConfirmation")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
guard viewModel.selectedTool != .brush else {
|
||||||
|
DebugLogger.log("Tap ignored - brush tool selected")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// Skip tap if in line brush mode
|
// Skip tap if in line brush mode
|
||||||
if viewModel.selectedTool == .wire && viewModel.isLineBrushMode {
|
if viewModel.selectedTool == .wire && viewModel.isLineBrushMode {
|
||||||
|
DebugLogger.log("Tap ignored - line brush mode")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
let imagePoint = convertViewPointToImagePoint(value.location, in: geometry.size)
|
let imagePoint = convertViewPointToImagePoint(value.location, in: geometry.size)
|
||||||
|
DebugLogger.log("Converted to image point: \(imagePoint)")
|
||||||
Task {
|
Task {
|
||||||
await viewModel.handleTap(at: imagePoint)
|
await viewModel.handleTap(at: imagePoint)
|
||||||
}
|
}
|
||||||
@@ -146,9 +176,11 @@ struct CanvasView: View {
|
|||||||
private func lineBrushGesture(in geometry: GeometryProxy) -> some Gesture {
|
private func lineBrushGesture(in geometry: GeometryProxy) -> some Gesture {
|
||||||
DragGesture(minimumDistance: 0)
|
DragGesture(minimumDistance: 0)
|
||||||
.onChanged { value in
|
.onChanged { value in
|
||||||
|
// Only activate for wire tool in line brush mode
|
||||||
guard viewModel.selectedTool == .wire,
|
guard viewModel.selectedTool == .wire,
|
||||||
viewModel.isLineBrushMode,
|
viewModel.isLineBrushMode else { return }
|
||||||
!viewModel.isProcessing,
|
|
||||||
|
guard !viewModel.isProcessing,
|
||||||
!viewModel.showingMaskConfirmation else { return }
|
!viewModel.showingMaskConfirmation else { return }
|
||||||
|
|
||||||
let imagePoint = convertViewPointToImagePoint(value.location, in: geometry.size)
|
let imagePoint = convertViewPointToImagePoint(value.location, in: geometry.size)
|
||||||
|
|||||||
Reference in New Issue
Block a user