SwiftUI:在没有 #available 的不同 iOS 版本之间使用视图修饰符 [英] SwiftUI: using view modifiers between different iOS versions without #available

查看:35
本文介绍了SwiftUI:在没有 #available 的不同 iOS 版本之间使用视图修饰符的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用以下代码片段(在 Xcode 13 Beta 5 和部署目标设置为 14.0)根据 iOS 版本有条件地应用视图修饰符:

I use the following code snippet (in Xcode 13 Beta 5 and deployment target set to 14.0) to apply view modifiers conditionally according to iOS version:

struct ContentView: View {
    var body: some View {
        Text("Hello, world!")
            .modifyFor(iOS14: {
                $0.onAppear {
                    //do some stuff
                }
            }, iOS15: {
                $0.task { //<---- Error: 'task(priority:_:)' is only available in iOS 15.0 or newer
                    //do some stuff
                }
            })
    }
}

struct CompatibleView<Input: View,
                      Output14: View,
                      Output15: View>: View {
    var content: Input
    var iOS14modifier: ((Input) -> Output14)?
    var iOS15modifier: ((Input) -> Output15)?
    
   @ViewBuilder var body: some View {
        if #available(iOS 15, *) {
            if let modifier = iOS15modifier {
                 modifier(content)
            }
            else { content }
        }
        else {
            if let modifier = iOS14modifier {
                 modifier(content)
            }
            else { content }
        }
    }
}

extension View {
    func modifyFor<T: View, U: View>(iOS14: ((Self) -> T)? = nil,
                                     iOS15: ((Self) -> U)? = nil) -> some View {
         CompatibleView(content: self,
                                  iOS14modifier: iOS14,
                                  iOS15modifier: iOS15)
    }
}

只要我不使用 iOS 15 的视图修饰符,此代码就可以很好地工作,但是如果我想使用这些修饰符中的任何一个(例如 Task),那么我需要使用#available 指令这是我不想选择的选项,因为我的代码库很大,有很多部分应该采用新的 iOS 15 修饰符并使用 #available 代码中的任何地方都会让它看起来像一盘烤宽面条.

this code works great as long as I don't use iOS 15's view modifiers, but if I want to use any of those modifiers (like Task for ex.) then I need to use the #available directive which's an option I don't wanna opt in, because my codebase is large, there are many parts that should adopt the new iOS 15 modifiers and by using #available everywhere in the code will make it looks like a dish of Lasagna.

如何在不使用#available检查的情况下以干净的方式编译这段代码?

how to make this piece of code compiles in a clean way and without using the #available check ?

推荐答案

没有意义,因为即使你向后移植了一个名为 task 的修饰符(这通常是解决这个问题的方式)您将无法在内部使用 async/await 的所有魔力,而这正是它的设计目的.如果您有充分的理由不针对 iOS 15(我不知道有什么好的理由),那么只需继续像往常一样使用 onAppear 和标准调度队列异步或在 @ 中组合状态对象.

There is no point because even if you did back-port a modifier named task (which is how this problem is normally solved) you won’t be able to use all the magic of async/await inside which is what it was designed for. If you have a good reason for not targeting iOS 15 (I don’t know any good ones) then just continue to use onAppear as normal and either standard dispatch queue async or Combine in an @StateObject.

这篇关于SwiftUI:在没有 #available 的不同 iOS 版本之间使用视图修饰符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆