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)
        }
    }
}

 

文哥博客(https://wenge365.com)属于文野个人博客,欢迎浏览使用

联系方式:qq:52292959 邮箱:52292959@qq.com

备案号:粤ICP备18108585号 友情链接