The*_*eil 4 macos cross-platform ios size-classes swiftui
尝试在macOS(本机,而不是 Catalyst)上引用@Environment
对象会导致以下错误: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
}
}
}
Run Code Online (Sandbox Code Playgroud)
The*_*eil 14
确实,macOS 本身不支持horizontalSizeClass
和verticalSizeClass
,但好消息是添加它们很容易。
您可以通过创建符合 的a 来定义自己的@Environment
对象,然后使用它来扩展。struct
EnvironmentKey
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
Run Code Online (Sandbox Code Playgroud)
完成此操作后,您就不需要为 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
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
您甚至可以将这些扩展放入一个框架中以供更广泛的使用,只要您将它们定义为public
.
归档时间: |
|
查看次数: |
1877 次 |
最近记录: |