Add interactive swipe-to-dismiss for iOS toasts

Toast cards now follow the finger upward and dismiss on either a
sufficient drag or a fast flick (via predicted-end translation). The
auto-dismiss timer pauses while the user is dragging and re-arms if
they release without dismissing.
This commit is contained in:
Arkadiusz Fal
2026-05-08 03:00:29 +02:00
parent 4f763373c1
commit b163864628
3 changed files with 69 additions and 16 deletions

View File

@@ -31,12 +31,15 @@ struct ToastOverlayView: View {
onDismiss: {
toastManager?.dismiss(id: toast.id)
},
onAction: toast.action?.handler
onAction: toast.action?.handler,
onDragBegan: {
toastManager?.pauseAutoDismiss(id: toast.id)
},
onDragCancelled: {
toastManager?.resumeAutoDismiss(id: toast.id)
}
)
.transition(.move(edge: .top).combined(with: .opacity))
#if !os(tvOS)
.gesture(swipeGesture(for: toast))
#endif
}
}
.padding(.top, topPadding)
@@ -56,18 +59,6 @@ struct ToastOverlayView: View {
return 60
#endif
}
#if !os(tvOS)
private func swipeGesture(for toast: Toast) -> some Gesture {
DragGesture()
.onEnded { value in
// Swipe up to dismiss
if value.translation.height < -50 {
toastManager?.dismiss(id: toast.id)
}
}
}
#endif
}
// MARK: - View Extension