So I have a sheet like this
.sheet(item: $logMyPractice, content: { item in
AssesmentRecorderView(
assessment: DrillModel(
questions: [
.init(prompt: "Question 1", resultValue: .integer),
]
),
completion: { date, answers in
print("response", date, answers)
// custom logic, save in the db
})
.presentationDetents([.fraction(0.85), .large ])
}
What is happening is that I need to open that sheet from a different views.
I could copy/paste it to the separate views but it's not following a DRY
concept.
I could create an ObservableObject
in the main view that holds information about the sheet and attach it as a environmentObject
, but I wonder if there's a better approach?
Here comes the power of the ViewModifier
You can do something like this
struct ContentView: View {
@State var isPresented: Bool = false
var body: some View {
VStack {
Image(systemName: "globe")
.imageScale(.large)
.foregroundColor(.accentColor)
Button {
isPresented = true
} label: {
Text("Hello, world!")
}
}
.customSheet(isPresented: $isPresented) { singleString, arrayString in
print(singleString)
print(arrayString)
}
}
}
struct CustomSheetViewModifier: ViewModifier {
@Binding var isPresented: Bool
let completionHandler: ((String, [String]) -> Void)?
func body(content: Content) -> some View {
content
.sheet(isPresented: $isPresented) {
Button {
completionHandler?("Done", ["Button 1", "Button 2"])
isPresented = false
} label: {
Text("Click me")
}
}
}
}
extension View {
func customSheet(isPresented: Binding<Bool>, completionHandler: ((String, [String]) -> Void)?) -> some View {
modifier(CustomSheetViewModifier(isPresented: isPresented, completionHandler: completionHandler))
}
}
and in your case you will replace the body of the CustomeSheetViewModifier with this
func body(content: Content) -> some View {
content
.sheet(isPresented: $isPresented) {
AssesmentRecorderView(
assessment: DrillModel(
questions: [
.init(prompt: "Question 1", resultValue: .integer),
]
),
completion: { date, answers in
completionHandler(date, answers)
})
.presentationDetents([.fraction(0.85), .large ])
}
}
assuming that the date is a string and the answers is an array of Strings you of course can replace the completionHandler parameters with whatever you like