优化 SwiftUI 支持多平台代码
· 阅读需 4 分钟
对于使用 SwiftUI 的多平台项目,它确实可以显著加快为多个平台开发的速度。然而,由于苹果的各个平台之间存在足够的差异,因 此最终你的代码库将充斥着#if os()
判断。
我以前曾写过关于在 SwiftUI 应用程序中共享跨平台代码的文章,其中我以UIPasteboard
和NSPasteboard
之间的微小差异为例,以使应用程序在 iOS 和 macOS 上运行。但是,平台之间的 API 差异并不能解决您可能需要进行特定于平台的更改的所有情况。例如,UIKit 在 watchOS 和 tvOS 上(部分)可用。而 SwiftUI 在所有平台上都可用。
最好的平台特定差异示例之一是 UI 布局代码的填充值。David Smith 上周写了一篇关于他的一个手表应用程序的“像素完美”设计的文章。虽然他是针对每个手表设备尺寸调整 UI 布局而不是不同的平台,但核心问题是相同的:即使是自适应的 UI 布局代码也不能总是通用应用。
你最终得到的代码看起来像这样:
var body: some View {
MyCustomView()
#if os(iOS)
.padding(10)
#elseif os(watchOS)
.padding(4)
#else // macOS
.padding(24)
#endif
}
使用#if os()
编写的代码很难阅读,增加了认知负荷,并且 Xcode 默认的#if os()
格式非常丑陋。我们可以通过一个简单的扩展来避免在每个地方编写#if os()
,同时使这段代码更易于阅读。
extension Double {
init(iOS: Self, watchOS: Self, macOS: Self) {
#if os(iOS)
self = iOS
#elseif os(watchOS)
self = watchOS
#else // macOS
self = macOS
#endif
}
}
然后我们的布局代码简化为以下形式:
var body: some View {
MyCustomView()
.padding(Double(iOS: 10, watchOS: 4, macOS: 24))
}