如何将 fullScreenCover 与 iOS 14 一起使用,但适用于 13

Jor*_*n H 10 ios swiftui

想象一下,你已经构建了一个使用sheetAPI 来呈现模式表的屏幕,现在你想fullScreenCover在 iOS 14 上运行时使用 SwiftUI 2.0 。你是怎么做到的?Xcode 提供建议:

  • 添加 if #available 版本检查
  • 添加@available 属性

如果您使用#available 版本检查,它会用#available 包装所有范围内的代码,因此您必须复制所有这些以更改那一行代码。如果使用@available,则必须复制整个结构。

有没有办法让“内联”逻辑说明 iOS 14 是否添加了这个修饰符,否则回到这个修饰符,而不必复制所有其余的视图代码?

一个例子:

VStack {
    //a lot of other views here
}
.sheet(isPresented: self.$showingSomeView) { //TODO: Replace sheet with fullScreenCover for iOS 14+
    SomeView()
}
Run Code Online (Sandbox Code Playgroud)

Asp*_*eri 21

这是可能的方法

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)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)