diff --git a/Sources/BottomSheet/BottomSheet.swift b/Sources/BottomSheet/BottomSheet.swift index f287ae7..b93db07 100644 --- a/Sources/BottomSheet/BottomSheet.swift +++ b/Sources/BottomSheet/BottomSheet.swift @@ -18,6 +18,7 @@ public struct BottomSheet: View { @State private var previousDragValue: DragGesture.Value? @Binding var isPresented: Bool + @State var gestureEnded: Bool private let height: CGFloat private let topBarHeight: CGFloat private let topBarCornerRadius: CGFloat @@ -25,7 +26,8 @@ public struct BottomSheet: View { private let contentBackgroundColor: Color private let topBarBackgroundColor: Color private let showTopIndicator: Bool - + private let animation: Animation + public init( isPresented: Binding, height: CGFloat, @@ -34,11 +36,14 @@ public struct BottomSheet: View { topBarBackgroundColor: Color = Color(.systemBackground), contentBackgroundColor: Color = Color(.systemBackground), showTopIndicator: Bool, + animation: Animation = .interactiveSpring(), @ViewBuilder content: () -> Content ) { self.topBarBackgroundColor = topBarBackgroundColor self.contentBackgroundColor = contentBackgroundColor self._isPresented = isPresented + self._gestureEnded = State(initialValue: true) + self.animation = animation self.height = height self.topBarHeight = topBarHeight if let topBarCornerRadius = topBarCornerRadius { @@ -65,7 +70,7 @@ public struct BottomSheet: View { .frame(height: sheetHeight(in: geometry) - min(self.draggedOffset*2, 0)) .background(self.contentBackgroundColor) .cornerRadius(self.topBarCornerRadius, corners: [.topLeft, .topRight]) - .animation(.interactiveSpring()) + .animation(self.gestureEnded ? .interactiveSpring() : self.animation) .offset(y: self.isPresented ? (geometry.size.height/2 - sheetHeight(in: geometry)/2 + geometry.safeAreaInsets.bottom + self.draggedOffset) : (geometry.size.height/2 + sheetHeight(in: geometry)/2 + geometry.safeAreaInsets.bottom)) } } @@ -80,8 +85,11 @@ public struct BottomSheet: View { .black .opacity(grayBackgroundOpacity) .edgesIgnoringSafeArea(.all) - .animation(.interactiveSpring()) - .onTapGesture { self.isPresented = false } + .animation(self.gestureEnded ? .interactiveSpring() : self.animation) + .onTapGesture { + self.isPresented = false + self.gestureEnded = false + } } fileprivate func topBar(geometry: GeometryProxy) -> some View { @@ -109,9 +117,11 @@ public struct BottomSheet: View { let velocityY = heightDiff / timeDiff if velocityY > 1400 { self.isPresented = false + self.gestureEnded = false return } } + self.gestureEnded = true self.previousDragValue = value }) @@ -120,6 +130,7 @@ public struct BottomSheet: View { if offsetY > self.dragToDismissThreshold { self.isPresented = false } + self.gestureEnded = false self.draggedOffset = 0 }) ) diff --git a/Sources/BottomSheet/ViewExtension.swift b/Sources/BottomSheet/ViewExtension.swift index d70fa9f..06cf922 100644 --- a/Sources/BottomSheet/ViewExtension.swift +++ b/Sources/BottomSheet/ViewExtension.swift @@ -18,6 +18,7 @@ public extension View { contentBackgroundColor: Color = Color(.systemBackground), topBarBackgroundColor: Color = Color(.systemBackground), showTopIndicator: Bool = true, + animation: Animation = .interactiveSpring(), @ViewBuilder content: @escaping () -> Content ) -> some View { ZStack { @@ -29,6 +30,7 @@ public extension View { topBarBackgroundColor: topBarBackgroundColor, contentBackgroundColor: contentBackgroundColor, showTopIndicator: showTopIndicator, + animation: animation, content: content) } } @@ -41,6 +43,7 @@ public extension View { contentBackgroundColor: Color = Color(.systemBackground), topBarBackgroundColor: Color = Color(.systemBackground), showTopIndicator: Bool = true, + animation: Animation = .interactiveSpring(), @ViewBuilder content: @escaping (Item) -> Content ) -> some View { let isPresented = Binding { @@ -58,7 +61,8 @@ public extension View { topBarCornerRadius: topBarCornerRadius, contentBackgroundColor: contentBackgroundColor, topBarBackgroundColor: topBarBackgroundColor, - showTopIndicator: showTopIndicator + showTopIndicator: showTopIndicator, + animation: animation ) { if let unwrapedItem = item.wrappedValue { content(unwrapedItem) diff --git a/iOS Example/Sources/ContentView.swift b/iOS Example/Sources/ContentView.swift index 3ea0554..0f7ce94 100644 --- a/iOS Example/Sources/ContentView.swift +++ b/iOS Example/Sources/ContentView.swift @@ -26,7 +26,8 @@ struct ContentView: View { height: 370, topBarHeight: 16, topBarCornerRadius: 16, - showTopIndicator: false + showTopIndicator: false, + animation: .spring() ) { MapSettingView() }