Reputation: 2493
we have several SwiftUI screens that are presented as sheet. all of then can be dismissed by clicking a button.
so basically all of them have these 2 in common:
@Environment(\.presentationMode) var presentationMode
func dismiss() {
presentationMode.wrappedValue.dismiss()
}
how can i declare them only once and just reuse them only in specific views? i cannot use inheritance since they are stucts, extensions cannot contain state (except using a holder struct) and would add these to all instances of the same view type.
Upvotes: 1
Views: 465
Reputation: 257563
The .presentationMode
is available throughout current view hierarchy, so we can use this feature to wrap & manage dismiss in some modifier.
Here is a demo of solution based on button style, so any button can be specified as dismissing and it will dismiss current presentation.
Prepared with Xcode 12.1 / iOS 14.1
struct TestReuseDismissed: View {
@State private var isActive = false
var body: some View {
Button("Show Sheet") {
isActive = true
}
.sheet(isPresented: $isActive) {
Button("Dismiss", action: {
// do something before dismiss here !!
})
.buttonStyle(DismissButtonStyle())
}
}
}
struct DismissButtonStyle: PrimitiveButtonStyle {
@Environment(\.presentationMode) var presentationMode
func makeBody(configuration: Configuration) -> some View {
Button(action: {
configuration.trigger()
dismiss()
}) { configuration.label }
}
func dismiss() {
presentationMode.wrappedValue.dismiss()
}
}
Upvotes: 3