Skip to content

Commit 325c640

Browse files
committed
fix: The selectedDetentIdentifier value in Environment may not update if the selected Detent identifier is changed programmatically.
1 parent 8d69722 commit 325c640

File tree

2 files changed

+36
-40
lines changed

2 files changed

+36
-40
lines changed

README.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -347,7 +347,6 @@ struct ContentView: View {
347347

348348
# Known Issues
349349
- Largest undimmed detent seems to affect the dimming of accent color elements in parent views.
350-
- The `selectedDetentIdentifier` value in `Environment` may not update if the selected `Detent` identifier is changed programmatically.
351350

352351
# License
353352
PageSheet is released under the MIT license. See [LICENSE](LICENSE.md) for details.

Sources/PageSheet.swift

Lines changed: 36 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,19 @@ public enum PageSheet {
4141
@State
4242
private var configuration: Configuration = .default
4343

44+
@State
45+
private var selectedDetent: Detent.Identifier?
46+
4447
let content: Content
4548

4649
var body: some View {
47-
HostingView(configuration: $configuration, content: content)
50+
HostingView(configuration: $configuration, selectedDetent: $selectedDetent, content: content)
51+
.onChange(of: selectedDetent) { newValue in
52+
self.configuration.selectedDetentIdentifier = newValue
53+
}
54+
.onPreferenceChange(Preference.SelectedDetentIdentifier.self) { newValue in
55+
self.selectedDetent = newValue
56+
}
4857
.onPreferenceChange(Preference.GrabberVisible.self) { newValue in
4958
self.configuration.prefersGrabberVisible = newValue
5059
}
@@ -54,9 +63,6 @@ public enum PageSheet {
5463
.onPreferenceChange(Preference.LargestUndimmedDetentIdentifier.self) { newValue in
5564
self.configuration.largestUndimmedDetentIdentifier = newValue
5665
}
57-
.onPreferenceChange(Preference.SelectedDetentIdentifier.self) { newValue in
58-
self.configuration.selectedDetentIdentifier = newValue
59-
}
6066
.onPreferenceChange(Preference.EdgeAttachedInCompactHeight.self) { newValue in
6167
self.configuration.prefersEdgeAttachedInCompactHeight = newValue
6268
}
@@ -71,6 +77,7 @@ public enum PageSheet {
7177
self.configuration.preferredCornerRadius = newValue
7278
}
7379
.ignoresSafeArea()
80+
.environment(\._selectedDetentIdentifier, self.selectedDetent)
7481
}
7582
}
7683

@@ -82,9 +89,12 @@ public enum PageSheet {
8289
var configuration: Configuration = .default {
8390
didSet {
8491
if let sheet = self.sheetPresentationController {
85-
sheet.delegate = self
92+
if sheet.delegate == nil {
93+
sheet.delegate = self
94+
}
95+
96+
let config = self.configuration
8697
sheet.animateChanges {
87-
let config = self.configuration
8898
sheet.prefersGrabberVisible = config.prefersGrabberVisible
8999
sheet.detents = config.detents
90100
sheet.largestUndimmedDetentIdentifier = config.largestUndimmedDetentIdentifier
@@ -94,70 +104,57 @@ public enum PageSheet {
94104
sheet.prefersScrollingExpandsWhenScrolledToEdge =
95105
config.prefersScrollingExpandsWhenScrolledToEdge
96106
sheet.preferredCornerRadius = config.preferredCornerRadius
97-
98-
self.selectedDetentChanged?(config.selectedDetentIdentifier)
99107
sheet.selectedDetentIdentifier = config.selectedDetentIdentifier
100108
}
101109
}
102110
}
103111
}
104112

105-
var selectedDetentChanged: ((Detent.Identifier?) -> Void)?
113+
@Binding
114+
var selectedDetent: Detent.Identifier?
115+
116+
init(rootView: Content, selectedDetent: Binding<Detent.Identifier?>) {
117+
self._selectedDetent = selectedDetent
118+
super.init(rootView: rootView)
119+
}
120+
121+
@MainActor @objc required dynamic init?(coder aDecoder: NSCoder) {
122+
fatalError("init(coder:) has not been implemented")
123+
}
106124

107125
// MARK: UISheetPresentationControllerDelegate
108126

109127
func sheetPresentationControllerDidChangeSelectedDetentIdentifier(
110128
_ sheet: UISheetPresentationController
111129
) {
112-
selectedDetentChanged?(sheet.selectedDetentIdentifier)
130+
self.selectedDetent = sheet.selectedDetentIdentifier
113131
}
114132
}
115133

116134
// MARK: - HostingView
117135

118136
fileprivate struct HostingView<Content: View>: UIViewControllerRepresentable {
119-
typealias ModifiedView = ModifiedContent<
120-
Content, ApplySelectedDetentEnvironmentValueViewModifier
121-
>
122-
123137
@Binding
124138
var configuration: Configuration
125139

140+
@Binding
141+
var selectedDetent: Detent.Identifier?
142+
126143
@State
127144
private var selectedDetentIdentifier: Detent.Identifier?
128145

129146
let content: Content
130147

131-
func makeUIViewController(context: Context) -> HostingController<ModifiedView> {
148+
func makeUIViewController(context: Context) -> HostingController<Content> {
132149
HostingController(
133-
rootView: content.modifier(
134-
ApplySelectedDetentEnvironmentValueViewModifier(
135-
selectedDetentIdentifier: $selectedDetentIdentifier
136-
)
137-
)
150+
rootView: content,
151+
selectedDetent: $selectedDetent
138152
)
139153
}
140154

141-
func updateUIViewController(_ controller: HostingController<ModifiedView>, context: Context) {
142-
controller.selectedDetentChanged = { newDetent in
143-
// FIXME: this causes issues since it is drawing during a state update. Need to figure out how to... not do that.
144-
// self.selectedDetentIdentifier = $0
145-
}
155+
func updateUIViewController(_ controller: HostingController<Content>, context: Context) {
146156
controller.configuration = configuration
147-
controller.rootView = content.modifier(
148-
ApplySelectedDetentEnvironmentValueViewModifier(
149-
selectedDetentIdentifier: $selectedDetentIdentifier
150-
)
151-
)
152-
}
153-
}
154-
155-
fileprivate struct ApplySelectedDetentEnvironmentValueViewModifier: ViewModifier {
156-
@Binding
157-
var selectedDetentIdentifier: Detent.Identifier?
158-
159-
func body(content: Content) -> some View {
160-
content.environment(\._selectedDetentIdentifier, selectedDetentIdentifier)
157+
controller.rootView = content
161158
}
162159
}
163160
}

0 commit comments

Comments
 (0)