Skip to content

Commit f0ffe7f

Browse files
authored
feat: allow any view to be dropped (#14)
1 parent 5abc473 commit f0ffe7f

File tree

2 files changed

+24
-10
lines changed

2 files changed

+24
-10
lines changed

Sources/DropView/View Modifiers/ItemDropViewPresenter.swift

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import SwiftUI
1111

1212
/// A `struct` defining a view modifier
1313
/// tasked with overlaying the drop view.
14-
private struct ItemDropViewPresenter<Item: Identifiable, C: View, L: View, R: View>: ViewModifier {
14+
private struct ItemDropViewPresenter<Item: Identifiable, C: View>: ViewModifier {
1515
/// The drag gesture translation.
1616
@GestureState var translation: CGFloat = 0
1717

@@ -21,8 +21,10 @@ private struct ItemDropViewPresenter<Item: Identifiable, C: View, L: View, R: Vi
2121
let alignment: VerticalAlignment
2222
/// The auto-dismiss time interval.
2323
let timer: TimeInterval
24+
/// Whether it should dismiss the drop view on drag or not.
25+
let shouldDismissOnDrag: Bool
2426
/// The drop view factory.
25-
let dropView: (Item) -> DropView<C, L, R>
27+
let dropView: (Item) -> C
2628

2729
/// The associated transition edge.
2830
private var edge: Edge {
@@ -49,7 +51,9 @@ private struct ItemDropViewPresenter<Item: Identifiable, C: View, L: View, R: Vi
4951
)
5052
.gesture(
5153
// Drag-to-dismiss.
52-
DragGesture()
54+
!shouldDismissOnDrag
55+
? nil
56+
: DragGesture()
5357
.updating($translation) { change, state, _ in
5458
switch alignment {
5559
case .center: state = min(change.translation.width, 0)
@@ -83,18 +87,21 @@ public extension View {
8387
/// - isPresented: An optional `Identifiable` binding.
8488
/// - alignment: A valid `VerticalAlignment`. Defaults to `.top`.
8589
/// - timer: The time before it gets autodismissed. Defaults to `2`.
90+
/// - shouldDismissOnDrag: Whether dragging the drop view should dismiss it or not. Defaults to `true`.
8691
/// - content: The drop view factory.
8792
/// - returns: Some `View`.
88-
@ViewBuilder func drop<I: Identifiable, C: View, L: View, T: View>(
93+
@ViewBuilder func drop<I: Identifiable, C: View>(
8994
item: Binding<I?>,
9095
alignment: VerticalAlignment = .top,
9196
dismissingAfter timer: TimeInterval = 2,
92-
@ViewBuilder content: @escaping (I) -> DropView<C, L, T>
97+
dismissingOnDrag shouldDismissOnDrag: Bool = true,
98+
@ViewBuilder content: @escaping (I) -> C
9399
) -> some View {
94100
modifier(ItemDropViewPresenter(
95101
item: item,
96102
alignment: alignment,
97103
timer: timer,
104+
shouldDismissOnDrag: shouldDismissOnDrag,
98105
dropView: content
99106
))
100107
}

Sources/DropView/View Modifiers/ToggleDropViewPresenter.swift

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import SwiftUI
1111

1212
/// A `struct` defining a view modifier
1313
/// tasked with overlaying the drop view.
14-
private struct ToggleDropViewPresenter<C: View, L: View, R: View>: ViewModifier {
14+
private struct ToggleDropViewPresenter<C: View>: ViewModifier {
1515
/// The drag gesture translation.
1616
@GestureState var translation: CGFloat = 0
1717

@@ -21,8 +21,10 @@ private struct ToggleDropViewPresenter<C: View, L: View, R: View>: ViewModifier
2121
let alignment: VerticalAlignment
2222
/// The auto-dismiss time interval.
2323
let timer: TimeInterval
24+
/// Whether it should dismiss the drop view on drag or not.
25+
let shouldDismissOnDrag: Bool
2426
/// The drop view factory.
25-
let dropView: () -> DropView<C, L, R>
27+
let dropView: () -> C
2628

2729
/// The associated transition edge.
2830
private var edge: Edge {
@@ -49,7 +51,9 @@ private struct ToggleDropViewPresenter<C: View, L: View, R: View>: ViewModifier
4951
)
5052
.gesture(
5153
// Drag-to-dismiss.
52-
DragGesture()
54+
!shouldDismissOnDrag
55+
? nil
56+
: DragGesture()
5357
.updating($translation) { change, state, _ in
5458
switch alignment {
5559
case .center: state = min(change.translation.width, 0)
@@ -78,18 +82,21 @@ public extension View {
7882
/// - isPresented: An optional `Bool` binding.
7983
/// - alignment: A valid `VerticalAlignment`. Defaults to `.top`.
8084
/// - timer: The time before it gets autodismissed. Defaults to `2`.
85+
/// - shouldDismissOnDrag: Whether dragging the drop view should dismiss it or not. Defaults to `true`.
8186
/// - content: The drop view factory.
8287
/// - returns: Some `View`.
83-
@ViewBuilder func drop<C: View, L: View, T: View>(
88+
@ViewBuilder func drop<C: View>(
8489
isPresented: Binding<Bool>,
8590
alignment: VerticalAlignment = .top,
8691
dismissingAfter timer: TimeInterval = 2,
87-
@ViewBuilder content: @escaping () -> DropView<C, L, T>
92+
dismissingOnDrag shouldDismissOnDrag: Bool = true,
93+
@ViewBuilder content: @escaping () -> C
8894
) -> some View {
8995
modifier(ToggleDropViewPresenter(
9096
isPresented: isPresented,
9197
alignment: alignment,
9298
timer: timer,
99+
shouldDismissOnDrag: shouldDismissOnDrag,
93100
dropView: content
94101
))
95102
}

0 commit comments

Comments
 (0)