diff --git a/Sources/FlowStack/FlowTransition.swift b/Sources/FlowStack/FlowTransition.swift index 8967300..30edb9f 100644 --- a/Sources/FlowStack/FlowTransition.swift +++ b/Sources/FlowStack/FlowTransition.swift @@ -162,13 +162,16 @@ extension AnyTransition { let scaleRatio = context.shouldScaleHorizontally ? zoomRect.size.width / proxy.size.width : 1.0 content - .onInteractiveDismissGesture(threshold: 80, isEnabled: !isDisabled, isDismissing: isDismissing, swipeUpToDismiss: context.swipeUpToDismiss, onDismiss: { + .onInteractiveDismissGesture(threshold: 80, isDismissing: isDismissing, swipeUpToDismiss: context.swipeUpToDismiss, onDismiss: { + defer { isDismissing = true } + guard !isDisabled else { return } dismiss() isDismissing = true }, onPan: { offset in - snapCornerRadiusZero = false - isEnded = false - panOffset = offset + defer { self.isEnded = false } + guard !isDisabled else { return } + self.snapCornerRadiusZero = false + self.panOffset = offset }, onEnded: { isDismissing in // TODO: FS-34: Handle snap corner radius 0 on interactive dismiss cancel withTransaction(transaction) { diff --git a/Sources/FlowStack/View+InteractiveDismiss.swift b/Sources/FlowStack/View+InteractiveDismiss.swift index cc75714..c19ca55 100644 --- a/Sources/FlowStack/View+InteractiveDismiss.swift +++ b/Sources/FlowStack/View+InteractiveDismiss.swift @@ -42,7 +42,6 @@ struct InteractiveDismissContainer: UIViewControllerRepresentable { var threshold: Double var onPan: (CGPoint) -> Void - var isEnabled: Bool var isDismissing: Bool var swipeUpToDismiss: Bool @@ -57,12 +56,11 @@ struct InteractiveDismissContainer: UIViewControllerRepresentable { } func updateUIViewController(_ uiViewController: InteractiveDismissViewController, context: Context) { - context.coordinator.isEnabled = isEnabled context.coordinator.isDismissing = isDismissing } func makeCoordinator() -> InteractiveDismissCoordinator { - InteractiveDismissCoordinator(threshold: threshold, onPan: onPan, isEnabled: isEnabled, isDismissing: isDismissing, swipeUpToDismiss: swipeUpToDismiss, onDismiss: onDismiss, onEnded: onEnded) + InteractiveDismissCoordinator(threshold: threshold, onPan: onPan, isDismissing: isDismissing, swipeUpToDismiss: swipeUpToDismiss, onDismiss: onDismiss, onEnded: onEnded) } } @@ -127,12 +125,6 @@ class InteractiveDismissCoordinator: NSObject, ObservableObject, UIGestureRecogn var threshold: Double var onPan: (CGPoint) -> Void - var isEnabled: Bool { - didSet { - panGestureRecognizer.isEnabled = isEnabled - edgeGestureRecognizer.isEnabled = isEnabled - } - } var isDismissing: Bool { didSet { guard isDismissing else { return } @@ -177,11 +169,10 @@ class InteractiveDismissCoordinator: NSObject, ObservableObject, UIGestureRecogn } } - init(threshold: Double, onPan: @escaping (CGPoint) -> Void, isEnabled: Bool, isDismissing: Bool, swipeUpToDismiss: Bool, onDismiss: @escaping () -> Void, onEnded: @escaping (Bool) -> Void) { + init(threshold: Double, onPan: @escaping (CGPoint) -> Void, isDismissing: Bool, swipeUpToDismiss: Bool, onDismiss: @escaping () -> Void, onEnded: @escaping (Bool) -> Void) { self.threshold = threshold self.onPan = onPan - self.isEnabled = isEnabled self.isDismissing = isDismissing self.swipeUpToDismiss = swipeUpToDismiss self.onDismiss = onDismiss @@ -193,12 +184,10 @@ class InteractiveDismissCoordinator: NSObject, ObservableObject, UIGestureRecogn self.panGestureRecognizer = UIPanGestureRecognizer(target: self, action: #selector(panGestureUpdated(recognizer:))) self.panGestureRecognizer.delegate = self - self.panGestureRecognizer.isEnabled = isEnabled self.edgeGestureRecognizer = UIScreenEdgePanGestureRecognizer(target: self, action: #selector(edgeGestureUpdated(recognizer:))) self.edgeGestureRecognizer.edges = [.left] self.edgeGestureRecognizer.delegate = self - self.edgeGestureRecognizer.isEnabled = isEnabled self.panGestureRecognizer.require(toFail: self.edgeGestureRecognizer) } @@ -223,7 +212,7 @@ class InteractiveDismissCoordinator: NSObject, ObservableObject, UIGestureRecogn onPan(offset) let shouldDismiss = offset.y > threshold || (offset.x > threshold && isEdge) || (-offset.y > threshold * 2 && swipeUpToDismiss) - if shouldDismiss != isPastThreshold && shouldDismiss { + if shouldDismiss != isPastThreshold && shouldDismiss, edgeGestureRecognizer.isEnabled, panGestureRecognizer.isEnabled { impactGenerator.impactOccurred() } @@ -231,7 +220,6 @@ class InteractiveDismissCoordinator: NSObject, ObservableObject, UIGestureRecogn if hasEnded { if shouldDismiss { - isEnabled = false onDismiss() isPastThreshold = false } else { @@ -290,7 +278,7 @@ class InteractiveDismissCoordinator: NSObject, ObservableObject, UIGestureRecogn } extension View { - func onInteractiveDismissGesture(threshold: Double = 50, isEnabled: Bool = true, isDismissing: Bool = false, swipeUpToDismiss: Bool, onDismiss: @escaping () -> Void, onPan: @escaping (CGPoint) -> Void = { _ in }, onEnded: @escaping (Bool) -> Void = { _ in }) -> some View { - InteractiveDismissContainer(threshold: threshold, onPan: onPan, isEnabled: isEnabled, isDismissing: isDismissing, swipeUpToDismiss: swipeUpToDismiss, onDismiss: onDismiss, onEnded: onEnded, content: self) + func onInteractiveDismissGesture(threshold: Double = 50, isDismissing: Bool = false, swipeUpToDismiss: Bool, onDismiss: @escaping () -> Void, onPan: @escaping (CGPoint) -> Void = { _ in }, onEnded: @escaping (Bool) -> Void = { _ in }) -> some View { + InteractiveDismissContainer(threshold: threshold, onPan: onPan, isDismissing: isDismissing, swipeUpToDismiss: swipeUpToDismiss, onDismiss: onDismiss, onEnded: onEnded, content: self) } }