Skip to content

Commit 90f322e

Browse files
authored
feat: included support for out animation and optional selected detent (#21)
* feat: included support for out animation and optional selected detent * feat: make header optional when initializing sheetPlus * fix: prevent keyboard from closing the bottomsheet on open
1 parent cd970c3 commit 90f322e

5 files changed

Lines changed: 70 additions & 20 deletions

File tree

Example/BottomSheetExample/Apple Applications/StocksExample.swift

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,21 @@ import BottomSheet
1010

1111
struct StocksExample: View {
1212
@EnvironmentObject var settings: SheetSettings
13-
13+
1414
var body: some View {
15-
Color.clear
16-
.navigationBarTitleDisplayMode(.inline)
17-
.navigationTitle("\(settings.translation.rounded())")
18-
.onAppear {
19-
settings.isPresented = true
20-
settings.activeSheetType = .stocks
15+
VStack {
16+
Button("Close") {
17+
settings.isPresented.toggle()
2118
}
19+
20+
Color.clear
21+
.navigationBarTitleDisplayMode(.inline)
22+
.navigationTitle("\(settings.translation.rounded())")
23+
.onAppear {
24+
settings.isPresented = true
25+
settings.activeSheetType = .stocks
26+
}
27+
}
2228
}
2329
}
2430

@@ -51,6 +57,7 @@ struct StocksHeader: View {
5157
struct StocksMainContent: View {
5258
var body: some View {
5359
VStack(spacing: 0) {
60+
TextField("Test", text: .constant(""))
5461
ScrollView {
5562
ForEach(0..<5, id: \.self) { _ in
5663
newsRow

Example/BottomSheetExample/ExampleOverview.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,7 @@ struct ExampleOverview: View {
4242
return AnyView(
4343
StocksMainContent()
4444
.presentationDetentsPlus(
45-
[.height(244), .medium, .large],
46-
selection: $settings.selectedDetent
45+
[.height(244), .medium, .large]
4746
)
4847
)
4948
default:

Sources/BottomSheet/BottomSheet.swift

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,9 @@ struct SheetPlus<HContent: View, MContent: View, Background: View>: ViewModifier
4444
ZStack() {
4545
content
4646

47-
if isPresented {
48-
GeometryReader { geometry in
49-
VStack(spacing: 0) {
50-
Spacer()
51-
47+
VStack {
48+
if isPresented {
49+
GeometryReader { geometry in
5250
VStack(spacing: 0) {
5351
hcontent
5452
.contentShape(Rectangle())
@@ -99,7 +97,7 @@ struct SheetPlus<HContent: View, MContent: View, Background: View>: ViewModifier
9997
? limits.max - geometry.safeAreaInsets.top
10098
: limits.max
10199
)
102-
.offset(y: limits.max - translation)
100+
.offset(y: UIScreen.main.bounds.height - translation)
103101
.onChange(of: translation) { newValue in
104102
if limits.max == 0 { return }
105103
translation = min(limits.max, max(newValue, limits.min))
@@ -115,22 +113,44 @@ struct SheetPlus<HContent: View, MContent: View, Background: View>: ViewModifier
115113
)
116114
)
117115
.onDisappear {
116+
translation = 0
117+
detents = []
118+
offset = 0
119+
newValue = 0
120+
limits = (min: 0, max: 0)
121+
118122
onDismiss()
119123
}
120124
}
121125
.edgesIgnoringSafeArea([.bottom])
126+
.transition(.move(edge: .bottom))
122127
}
123128
}
129+
.animation(
130+
.interpolatingSpring(
131+
mass: animationCurve.mass,
132+
stiffness: animationCurve.stiffness,
133+
damping: animationCurve.damping
134+
)
135+
)
124136
}
125137
.onPreferenceChange(SheetPlusTranslation.self) { value in
126138
self.translationKey = value
127139
}
128140
.onPreferenceChange(SheetPlusConfiguration.self) { value in
141+
/// Quick hack to prevent the scrollview from resetting the height when keyboard shows up.
142+
/// Replace if the root cause has been located.
143+
if value.detents.count == 0 { return }
144+
129145
detents = value.detents
130-
limits = detentLimits(detents: detents)
131-
translation = value.$selection.wrappedValue.size
146+
limits = detentLimits(detents: value.detents)
147+
148+
if value.selection == .height(.zero) {
149+
translation = limits.min
150+
} else {
151+
translation = value.$selection.wrappedValue.size
152+
}
132153

133-
self.preferenceKey = value
134154
}
135155
}
136156
}

Sources/BottomSheet/Preference Keys/ConfigKey.swift

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@
88
import SwiftUI
99

1010
struct SheetPlusConfigKey: Equatable {
11-
let detents: Set<PresentationDetent>
11+
let id = UUID().uuidString
1212

13+
let detents: Set<PresentationDetent>
1314
@Binding var selection: PresentationDetent
1415

1516
init(
@@ -21,7 +22,7 @@ struct SheetPlusConfigKey: Equatable {
2122
}
2223

2324
static func == (lhs: SheetPlusConfigKey, rhs: SheetPlusConfigKey) -> Bool {
24-
return lhs.selection == rhs.selection
25+
return lhs.id == rhs.id
2526
}
2627
}
2728

Sources/BottomSheet/View Modifiers/View+SheetPlus.swift

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,29 @@ extension View {
3333
)
3434
}
3535

36+
public func sheetPlus<MContent: View, Background: View>(
37+
isPresented: Binding<Bool>,
38+
animationCurve: SheetAnimation = SheetAnimation(
39+
mass: SheetAnimationDefaults.mass,
40+
stiffness: SheetAnimationDefaults.stiffness,
41+
damping: SheetAnimationDefaults.damping
42+
),
43+
background: Background = Color(UIColor.systemBackground),
44+
onDismiss: @escaping () -> Void = {},
45+
main: () -> MContent
46+
) -> some View {
47+
modifier(
48+
SheetPlus(
49+
isPresented: isPresented,
50+
animationCurve: animationCurve,
51+
background: background,
52+
onDismiss: onDismiss,
53+
hcontent: { EmptyView() },
54+
mcontent: main
55+
)
56+
)
57+
}
58+
3659
public func presentationDetentsPlus(
3760
_ detents: Set<PresentationDetent>
3861
) -> some View {

0 commit comments

Comments
 (0)