尝试在 macOS( native ,而非 Catalyst)上引用 @Environment
对象 horizontalSizeClass
和 verticalSizeClass
会导致以下错误:
'horizontalSizeClass' is unavailable in macOS
'verticalSizeClass' is unavailable in macOS
我明白这些属性并不真正适用于 macOS,但这对创建通用的 SwiftUI View (即跨 macOS、iOS 等的跨平台)构成了一个很大的障碍。
一种解决方法是将所有特定于大小类的代码包装在条件编译中,但结果是大量重复和冗余(请参见下面的示例)。
有没有更有效的方法来处理这个问题?
通用 View 示例:
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 本身不支持 horizontalSizeClass
和 verticalSizeClass
,但好消息是添加它们很容易。
您可以定义自己的@Environment
对象,方法是创建一个符合EnvironmentKey
的struct
,然后使用它来扩展EnvironmentValues
。
在 macOS 上实现大小分类所需的全部内容如下。它们只是始终返回 .regular
,但足以实现与 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.self] }
set { self[HorizontalSizeClassEnvironmentKey.self] = newValue }
}
var verticalSizeClass: UserInterfaceSizeClass {
get { return self[VerticalSizeClassEnvironmentKey.self] }
set { self[VerticalSizeClassEnvironmentKey.self] = 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
。
关于ios - SwiftUI:用于通用(macOS 和 iOS) View 的 UserInterfaceSizeClass,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63526478/