如何集成SwiftUI框架

7
我们只能从iOS 13.0+开始使用框架SwiftUI。那么如何在部署目标为10.0或至少12.0的情况下引入此框架呢?
请看下图: enter image description here

7
你的第一句话基本上回答了第二句话,是吗? - rmaddy
@maddy,不应该没有办法。 可以使用类似 #available 13.0 的方式。 - Shamil
4
如果您的应用程序运行在iOS 12设备上,您将如何使用使用SwiftUI创建的用户界面?由于无法这样做,您是否计划为应用程序编写两个完全不同的用户界面?一个采用UIKit,另一个采用SwiftUI?那是一个痛苦的计划。 - rmaddy
3个回答

12
尽管@DenFav的说法绝对正确-支持使用SwiftUI部署目标低于iOS 13是一件麻烦的事情,但这是可能的。
步骤:
1. 弱链接该框架(我使用了这个answer):
“将-weak_framework SwiftUI添加到其他链接器标志中可以解决我的问题。”
2. 用canImport包装所有SwiftUI调用(见answer):
#if canImport(SwiftUI) && canImport(Combine)
这将允许您构建和存档部署目标为
可选:
现在的问题是:如何处理viewModels。我用自己的实现解决了这个问题。您可以在Ruuvi Station的public repo中检查解决方案。注意:代码很复杂(VIPER),这就是为什么我会简要描述主要思想的原因。
viewModel实现在Classes/Presentation/Binding中。
我正在使用这些viewModels,ObservableObject来包装它们以供SwiftUI使用。
您仍然可以观察SwiftUI代码中进行的更改。
结果是:iOS 13在呈现层使用SwiftUI代码,而iOS 12及以下版本则使用传统的UIKit代码

视图控制器负责确定是否可以使用SwiftUI代码。


尝试后,它可以在模拟器上编译并执行。但是无法归档 :( - Badrinath
我也尝试了上面提到的加上@available(iOS 13.0, iOSApplicationExtension 13.0, *),但是在尝试归档时得到了以下错误信息:Use of undeclared type 'View', Use of undeclared type 'AnyView'等。几乎所有来自SwiftUI的东西都是如此。有什么想法吗? - Jose Santos
1
经过数小时的研究和设置调整,我终于让它正常工作了。原来我的iOS部署目标设置为10.0,但上述建议适用于11.0及更高版本。因此,对于那些尽管遵循建议仍无法使其正常工作的人,请检查您的iOS部署目标。 - Jose Santos

2

构建阶段 → 链接二进制文件 → 添加SwiftUI.framework (状态:可选)

。最初的回答。
import SwiftUI

@available(iOS 13.0, *)
struct SwiftUIView : View {
    var body: some View {
        Text("Hello World!")
    }
}

@available(iOS 13.0, *)
struct SwiftUIView_Previews : PreviewProvider {
    static var previews: some View {
        SwiftUIView()
    }
}

这个目标的SwiftUI预览无法工作,但是您可以添加一个名为“SwiftUI预览”的特殊目标。

等价译文:此目标的SwiftUI预览不起作用,但是您可以添加一个名为“SwiftUI预览”的特殊目标进行预览。


这似乎不起作用。我有一个针对iOS 11的iOS项目,但我想使用SwiftUI构建并重新构建我的UIKit视图之一,仅使其适用于iOS 13用户。我正在尝试使用此方法,但遇到了一些错误。您是否曾经能够让它工作? - MikeG
@MikeG,这在我当前的 iOS 项目中针对 iOS 12 是有效的。你遇到了什么错误? - Roman Kerimov
4个不同的错误: 1)从非协议类型'View'继承 2)函数声明了一个不透明的返回类型,但是在其主体中没有返回语句可以推断出底层类型 3)无法将返回类型为'Text'的返回表达式转换为返回类型为'some View' 4)类型'SwiftUIView_Previews'不符合协议'PreviewProvider' - MikeG
@MikeG,我再次检查了一个新的面向iOS 11的项目。它可以正常工作,我没有遇到这样的错误。你在项目中为所有视图和预览提供程序添加了@available(iOS 13.0, *)吗? - Roman Kerimov
感谢您的查看。我所做的测试只是添加了一个新文件,复制粘贴了您上面的代码,并在构建阶段的“链接二进制文件和库”部分中添加了SwiftUI.framework(状态:可选)。我的应用程序中有很多其他视图,但这些都是使用UIKit构建的UIView,不需要进行任何更改。我的应用程序中没有其他预览提供程序。 - MikeG
@MikeG,那我不知道在你的情况下可能是什么原因导致错误。 - Roman Kerimov

0

没有合理的方法来做到这一点。#available或@available允许您区分一些代码片段或整个类,但不包括应用程序本身。

您可以使用@available来消除SwiftUI结构或具有12.0部署目标的类的警告,但在这种情况下,您需要完全使用Swift UI从storyboards(.xib等)复制UI。此外,完全不同的“绑定”方法还将要求您重新实现该应用程序中的现有逻辑(无论您之前使用了什么样的架构)。任何VIPER、VIP、MVC都旨在向ViewController(View)发送一些数据更改通知,在Swift UI中,您需要使用可绑定对象。它还会导致您创建ViewModels的副本(如果您有这样的话),因为它们将是不同的。

结果?您有第二个UI实现,第二个视图模型实现,额外80%的Presenter实现(或者您使用的是什么)。只有数据库和rest管理器将被重用。如果您有非常好的架构,这是有效的。不要忘记您需要支持两个UI和逻辑分支。

有两种方法:重新开发几乎完整的应用程序以支持SwiftUI和UIKit,或者,如果您不想只支持iOS 13,则等待iOS 14发布,然后使用SwiftUI同时支持两者。


等待一年会有什么成果? - rmaddy
@maddy,我的意思是在 iOS 14 发布后,你将能够支持 iOS 13-14。目前你只能用 SwiftUI 支持 iOS 13。 - DenFav
这仍然意味着部署目标为iOS 13。这意味着只有一种方式,而不是两种。 - rmaddy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接