Imagine you've built a screen that utilizes the sheet
API to present modal sheets, and now with SwiftUI 2.0 you want to use fullScreenCover
instead when run on iOS 14. How do you do so? Xcode offers suggestions:
If you use the #available version check, it wraps all of that scoped code with #available, so you'd have to duplicate all of that to change that one line of code. If you use @available you have to duplicate the entire struct.
Is there a way to have "in-line" logic that says if iOS 14 add this modifier, otherwise fall back to this one, without having to duplicate all of the rest of the view code?
An example:
VStack {
//a lot of other views here
}
.sheet(isPresented: self.$showingSomeView) { //TODO: Replace sheet with fullScreenCover for iOS 14+
SomeView()
}
How to present a full screen modal view using fullScreenCover() SwiftUI's fullScreenCover() modifier gives us a presentation style for times when you want to cover as much of the screen as possible, and in code it works almost identically to regular sheets.
To use a sheet, give it something to show (some text, an image, a custom view, etc), add a Boolean that defines whether the detail view should be showing, then attach it to your main view as a modal sheet. Important: If you're targeting iOS 14 or below, you should use @Environment(\.
Modal views in SwiftUI are presented using the sheet modifier on a view or control. The simplest way is to have @State property to indicate when it should be visible. To hide the modal view, we can use the environment parameter or pass a binding to the modal view object.
The first option is to tell the view to dismiss itself using its presentation mode environment key. Any view can read its presentation mode using @Environment(\. presentationMode) , and calling wrappedValue. dismiss() on that will cause the view to be dismissed.
Here is possible approach
struct DemoCompatibleFullScreen: View {
@State private var activateFullScreen = false
var body: some View {
Button("Toggle") { self.activateFullScreen.toggle() }
.compatibleFullScreen(isPresented: $activateFullScreen) {
Text("I'm in Full Screen!")
}
}
}
extension View {
func compatibleFullScreen<Content: View>(isPresented: Binding<Bool>, @ViewBuilder content: @escaping () -> Content) -> some View {
self.modifier(FullScreenModifier(isPresented: isPresented, builder: content))
}
}
struct FullScreenModifier<V: View>: ViewModifier {
let isPresented: Binding<Bool>
let builder: () -> V
@ViewBuilder
func body(content: Content) -> some View {
if #available(iOS 14.0, *) {
content.fullScreenCover(isPresented: isPresented, content: builder)
} else {
content.sheet(isPresented: isPresented, content: builder)
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With