'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)
        }
    }
}

backup

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