This gist accompanies a blog post on Masilotti.com, How to manage multiple sheets in SwiftUI.
-
-
Save joemasilotti/b90d89cc8e78440bf21c25ce512a72b1 to your computer and use it in GitHub Desktop.
class SettingsSheet: SheetState<SettingsSheet.State> { | |
enum State { | |
case attributions | |
case email | |
case feedback | |
case instructions | |
case licenseAgreement | |
case privacyPolicy | |
} | |
} |
struct SettingsView: View { | |
@ObservedObject var sheet = SettingsSheet() | |
var body: some View { | |
VStack { | |
Button("Attributions") { self.sheet.state = .attributions } | |
Button("Email") { self.sheet.state = .email } | |
Button("Feedback") { self.sheet.state = .feedback } | |
Button("Instructions") { self.sheet.state = .instructions } | |
Button("License Agreement") { self.sheet.state = .licenseAgreement } | |
Button("Privacy Policy") { self.sheet.state = .privacyPolicy } | |
} | |
.sheet(isPresented: $sheet.isShowing, content: sheetContent) | |
} | |
@ViewBuilder | |
private func sheetContent() -> some View { | |
if sheet.state == .attributions { | |
AttributionsView() | |
} else if sheet.state == .email { | |
EmailView() | |
} else if sheet.state == .feedback { | |
FeedbackView() | |
} else if self.sheet.state == .instructions { | |
InstructionsView() | |
} else if self.sheet.state == .licenseAgreement { | |
WebView(url: Policy.licenseURL) | |
} else if self.sheet.state == .privacyPolicy { | |
WebView(url: Policy.privacyURL) | |
} else { | |
EmptyView() | |
} | |
} | |
} |
import Combine | |
class SheetState<State>: ObservableObject { | |
@Published var isShowing = false | |
@Published var state: State? { | |
didSet { isShowing = state != nil } | |
} | |
} |
As I still had issues with conflicting Bindings to other Observable Objects with your final and your pre-final solution (the one without the SheetState class), I posted this on StackOverflow with a - in my eyes - very elegant solution, as you can even get rid of the SheetState class this way:
https://stackoverflow.com/questions/64139912/swiftui-state-property-is-not-updated
To close the sheet, I followed this post:
https://daddycoding.com/2020/03/01/swiftui-sheet-modals/
At the end, I combined your solution with the other two. Thanks again!
Very nice! Do you have a version for iOS 13?
Well, the App I use it for has target iOS 13.5 and above, so yes, it should work for iOS 13. You can see it in action e.g. in FoodList.swift in my repo https://github.com/UlricusR/iOS-EasyFPU
Exactly, @UlricusR! I'm doing the same for a confirmation button in a form-style sheet.