SwiftUI在Multiplatform App中的几个通用问题解决方法
所属分类:ios | 发布于 2025-01-01
1、多平台内容封装
1.1、封装iOSContainer结构体来包装iOS平台内容
/**
IOSContainer, container for iOS
*/
struct IOSContainer<Content>: View where Content: View {
private let content: Content
init(@ViewBuilder content: () -> Content) {
self.content = content()
}
var body: some View {
#if os(iOS)
content
#else
EmptyView()
#endif
}
}
1.2、封装MacOSContainer结构体来包装macOS平台内容
/**
MacOSContainer, container for macOS
*/
struct MacOSContainer<Content>: View where Content: View {
private let content: Content
init(@ViewBuilder content: () -> Content) {
self.content = content()
}
var body: some View {
#if os(macOS)
content
#else
EmptyView()
#endif
}
}
1.3、封装PlatformContainer结构体,在一个结构体内包装iOS和macOS内容
/**
合二为一的Container,MacOSContainer和iOSContainer的组合
*/
struct PlatformContainer<Content>: View where Content: View {
private let iOSContent: Content
private let macOSContent: Content
init(@ViewBuilder iOSContent: () -> Content, @ViewBuilder macOSContent: () -> Content) {
self.iOSContent = iOSContent()
self.macOSContent = macOSContent()
}
var body: some View {
#if os(iOS)
iOSContent
#elseif os(macOS)
macOSContent
#else
EmptyView()
#endif
}
}
1.4、使用示例
// 合二为一的方法
PlatformContainer {
Text("iOS Content")
} macOSContent: {
Text("macOS Content")
}
// PlatformContainer的等价替换
IOSContainer {
Text("iOS Content")
}
MacOSContainer {
Text("macOS Content")
}
2、多平台Modifier封装
这个是在kavsoft的视频里看到的,感觉很好。
2.1、定义ModifierType
enum PlatformModiferType {
case iOS
case macOS
case tvOS
case visionOS
}
2.2、增加名叫platformModifier()的View扩展
extension View {
@ViewBuilder
func platformModifer<Content: View>(_ type: PlatformModiferType, @ViewBuilder content: (Self) -> Content) -> some View {
switch type {
case .iOS:
#if os(iOS)
content(self)
#else
self
#endif
case .macOS:
#if os(macOS)
content(self)
#else
self
#endif
case .tvOS:
#if os(tvOS)
content(self)
#else
self
#endif
case .visionOS:
#if os(visionOS)
content(self)
#else
self
#endif
}
}
}
2.3、使用示例
struct PlatformModiferDemo: View {
var body: some View {
VStack {
Image(systemName: "globe")
.imageScale(.large)
.foregroundStyle(.tint)
Text("Hello, world!")
}
.platformModifer(.iOS) { view in
view
.padding(25)
.background(.red)
}
.platformModifer(.macOS) { view in
view
.padding(10)
.background(.blue)
}
}
}