使用 SwiftUI 的一大收益就是可以像 Flutter 那样对 App 进行热更新,改动了UI的代码,会直接反映在模拟器或者是真机中,大大提升了编写用户界面的效率,不用改1px,运行,各种点击,然后查看效果的循环往复。但现在使用 SwiftUI 还为时过早,毕竟还是有大量 iOS 12 设备在运行,想要做大众软件,那还是要支持的。
那么,有没有办法能让 UIKit 编写的软件也能用上实时预览呢?其实是可以的……毕竟,SwiftUI 也能直接显示 UIKit 的控件。
首先我们来看看要在 Xcode 里预览 SwiftUI,需要做哪些工作:
1 2 3 4 5 6 |
struct Login_Preview: PreviewProvider { static var previews: some View { } } |
你只需要在任意一个 .swift 文件中加上上面的代码,Xcode 就会为你显示预览界面了,要让它加载 UIKit,我们需要实现一个 UIViewControllerRepresentable / UIViewRepresentable ,这取决于你要显示的是 UIViewController 还是 UIView 。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
import SwiftUI struct ViewControllerPreview: UIViewControllerRepresentable { typealias UIViewControllerType = UIViewController let viewControllerBuilder: () -> UIViewControllerType init(_ viewControllerBuilder: @escaping () -> UIViewControllerType) { self.viewControllerBuilder = viewControllerBuilder } @available(iOS 13.0.0, *) func makeUIViewController(context: Context) -> UIViewController { viewControllerBuilder() } func updateUIViewController(_ uiViewController: UIViewController, context: Context) { // Do nothing } } struct ViewPreview: UIViewRepresentable { let viewBuilder: () -> UIViewType init(_ viewBuilder: @escaping () -> UIViewType) { self.viewBuilder = viewBuilder } func makeUIView(context: Context) -> UIView { viewBuilder() } func updateUIView(_ uiView: UIView, context: Context) { // Do nothing } typealias UIViewType = UIView } |
这两个结构体是通用的,这样以后就可以直接使用了。但这有一个问题,当我们真正编译的时候,就需要修改最低支持版本号,因为毕竟它是依赖 SwiftUI 的,这就导致开发的时候需要调高版本号,在正式发布的时候再降低。
1 2 3 |
#if canImport(SwiftUI) && DEBUG // your code #endif |
我们可以用 Swift 宏来搞定这件事情,这样,编译器就可以自动判断当前是否支持 SwiftUI,且在正式发布的时候,会自动去掉这些代码了。
写好了这两个 Representable 之后,我们去需要预览的文件中,启用预览:
1 2 3 4 5 6 7 8 9 10 11 12 |
#if canImport(SwiftUI) && DEBUG import SwiftUI @available(iOS 13.0, *) struct Login_Preview: PreviewProvider { static var previews: some View { ViewControllerPreview { UINavigationController(rootViewController: LoginPage()) } } } #endif |
这样,Xcode 就能像使用 SwiftUI 那样来预览你的界面了!无论修改了什么,都可以实时显示在侧面的预览中!
注意,如果你使用了在每次编译后自动提升版本号的脚本,那可能会导致预览不能自动刷新,每次都要手动点 Resume,比如:
1 |
version=[crayon-673efd2136ee3119526238 inline="true" ]/usr/libexec/PlistBuddy -c "Print CFBundleVersion" $PRODUCT_SETTINGS_PATH |
version=
expr $version + 1
/usr/libexec/PlistBuddy -c “Set :CFBundleVersion $version” $PRODUCT_SETTINGS_PATH[/crayon]
我们需要修改它们以识别 Live Preview 模式:
1 2 3 4 |
if [ $ENABLE_PREVIEWS == "NO" ] then # your code to execute here version=[crayon-673efd2136ee8415868293 inline="true" ]/usr/libexec/PlistBuddy -c "Print CFBundleVersion" $PRODUCT_SETTINGS_PATH |
version=
expr $version + 1
/usr/libexec/PlistBuddy -c “Set :CFBundleVersion $version” $PRODUCT_SETTINGS_PATH
else
echo “Skipping the script because of preview mode”
fi
[/crayon]
这样,脚本就只会在正常编译时执行了,不会影响到 Xcode Live Preview。
参考文献
- How to Use Live Previews in UIKit
- mrabiciu/UIViewPreviewProvider
- SwiftUI: Automatic preview updating paused, always
本文由 落格博客 原创撰写:落格博客 » 为 UIKit 开启 Xcode Live Preview
转载请保留出处和原文链接:https://www.logcg.com/archives/3502.html