'How to use fullScreenCover with iOS 14 but sheet for 13
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:
- Add if #available version check
- Add @available attribute
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()
}
Solution 1:[1]
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)
}
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 |