在此示例中,蓝色矩形最初应在具有以下功能的设备上可见:.regular
尺寸类别并隐藏在具有.compact
尺寸等级。
我正在使用一个ObservableObject
called Settings
和@Published
多变的isVisible
管理矩形的可见性。我的问题是我不知道如何初始化Settings
与正确的horizontalSizeClass
从我的ContentView
。现在我正在使用.onAppear
改变的值isVisible
但这会触发.onReceive
。在紧凑型设备上,这会导致矩形在视图呈现时可见并淡出,而不是立即不可见。
我怎样才能初始化Settings
基于环境值,例如horizontalSizeClass
以便isVisible
从一开始就是正确的吗?
struct ContentView: View {
@Environment(\.horizontalSizeClass) var horizontalSizeClass
@StateObject var settings = Settings()
@State var opacity: CGFloat = 1
var body: some View {
VStack {
Button("Toggle Visibility") {
settings.isVisible.toggle()
}
.onReceive(settings.$isVisible) { _ in
withAnimation(.linear(duration: 2.0)) {
opacity = settings.isVisible ? 1 : 0
}
}
Rectangle()
.frame(width: 100, height: 100)
.foregroundColor(.blue)
.opacity(opacity)
}
.onAppear {
settings.isVisible = horizontalSizeClass == .regular // too late
}
}
}
class Settings: ObservableObject {
@Published var isVisible: Bool = true // can't get size class here
}
矩形在开始时不应该是可见的:
我们只需要执行依赖注入(已知环境是父环境,因此可以轻松注入子环境),并且使用内部视图很简单,例如
struct ContentView: View {
@Environment(\.horizontalSizeClass) var horizontalSizeClass
struct MainView: View {
// later knonw injection
@EnvironmentObject var settings: Settings
var body: some View {
VStack {
Button("Toggle Visibility") {
settings.isVisible.toggle()
}
Rectangle()
.frame(width: 100, height: 100)
.foregroundColor(.blue)
.opacity(settings.isVisible ? 1 : 0) // << direct dependency !!
}
.animation(.linear(duration: 2.0), value: settings.isVisible) // << explicit animation
}
}
var body: some View {
MainView() // << internal view
.environmentObject(
Settings(isVisible: horizontalSizeClass == .regular) // << initial injecttion !!
)
}
}
使用 Xcode 13.4 / iOS 15.5 进行测试
测试代码在这里 https://github.com/Asperi-Demo/4SwiftUI/blob/master/PlayOn_iOS/PlayOn_iOS/Findings/TestEnvironmentDepenencyInjectionIinternalView.swift
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)