![](/img/trans.png)
[英]SwiftUI alignment of "rating" views in two separate rows in Form for macOS and iOS
[英]SwiftUI: UserInterfaceSizeClass for Universal (macOS & iOS) Views
嘗試在 macOS(本機,而不是 Catalyst)上引用@Environment
對象 Horizo horizontalSizeClass
和verticalSizeClass
會導致以下錯誤:
“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 horizontalSizeClass
和verticalSizeClass
,但好消息是添加它們很容易。
您可以通過創建一個符合EnvironmentKey
的struct
來定義自己的@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.