簡體   English   中英

SwiftUI:通用(macOS 和 iOS)視圖的 UserInterfaceSizeClass

[英]SwiftUI: UserInterfaceSizeClass for Universal (macOS & iOS) Views

嘗試在 macOS(本機,而不是 Catalyst)上引用@Environment對象 Horizo horizontalSizeClassverticalSizeClass會導致以下錯誤:

“horizontalSizeClass”在 macOS 中不可用

“verticalSizeClass”在 macOS 中不可用

我很欣賞這些屬性並不真正適用於 macOS,但這對創建通用的 SwiftUI 視圖(即跨 macOS、iOS 等)構成了很大的障礙。

一種解決方法是將所有特定於大小類的代碼包裝在條件編譯中,但結果是大量重復和冗余(參見下面的示例)。

沒有更有效的方法來處理這個問題嗎?

通用視圖示例:

struct ExampleView: View {

    #if !os(macOS)
    @Environment(\.horizontalSizeClass) var horizontalSizeClass
    #endif

    private var item1: some View {
        Text("Example Item 1")
    }
    private var item2: some View {
        Text("Example Item 2")
    }
    private var item3: some View {
        Text("Example Item 3")
    }

    var body: some View {
        VStack {
            #if !os(macOS)
            if horizontalSizeClass == .compact {
                VStack {
                    item1
                    item2
                    item3
                }
            } else {
                HStack {
                    item1
                    item2
                    item3
                }
            }
            #else
            HStack {
                item1
                item2
                item3
            }
            #endif
        }
    }
}

確實,macOS 本身並不支持 Horizo horizontalSizeClassverticalSizeClass ,但好消息是添加它們很容易。

您可以通過創建一個符合EnvironmentKeystruct來定義自己的@Environment對象,然后使用它來擴展EnvironmentValues

在 macOS 上實現大小類所需的全部內容如下。 他們只是在任何時候都返回.regular ,但這足以 function 與 iOS 完全相同。

#if os(macOS)
enum UserInterfaceSizeClass {
    case compact
    case regular
}

struct HorizontalSizeClassEnvironmentKey: EnvironmentKey {
    static let defaultValue: UserInterfaceSizeClass = .regular
}
struct VerticalSizeClassEnvironmentKey: EnvironmentKey {
    static let defaultValue: UserInterfaceSizeClass = .regular
}

extension EnvironmentValues {
    var horizontalSizeClass: UserInterfaceSizeClass {
        get { return self[HorizontalSizeClassEnvironmentKey] }
        set { self[HorizontalSizeClassEnvironmentKey] = newValue }
    }
    var verticalSizeClass: UserInterfaceSizeClass {
        get { return self[VerticalSizeClassEnvironmentKey] }
        set { self[VerticalSizeClassEnvironmentKey] = newValue }
    }
}
#endif

有了這個,你就不需要 macOS 的任何特殊功能了。 例如:

struct ExampleView: View {

    @Environment(\.horizontalSizeClass) var horizontalSizeClass
    
    private var item1: some View {
        Text("Example Item 1")
    }
    private var item2: some View {
        Text("Example Item 2")
    }
    private var item3: some View {
        Text("Example Item 3")
    }
    
    var body: some View {
        VStack {
            if horizontalSizeClass == .compact {
                VStack {
                    item1
                    item2
                    item3
                }
            } else {
                HStack {
                    item1
                    item2
                    item3
                }
            }
        }
    }
}

您甚至可以將這些擴展放入一個框架中以便更廣泛地使用,只要您將它們定義為public

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM