下面是我想要做的事情的想法:我的应用程序的导航包含一个列表,它在点击手势上显示一个视图,这个视图由ViewModifier触发来执行动画。
简而言之:
MyList > MyViewModifier > MyView
由于我想将一些数据从列表传递到这个层次结构中的最终视图,所以我考虑使用@StateObject/@EnvironmentObject属性包装器。但我刚刚意识到,我不能像对待视图那样,将.environmentObject(xx)传递给ViewModifier。
下面是我到目前为止掌握的代码:
struct TestModel: Identifiable {
var id: Int
var name: String
//@Published var whateverData I would like to fetch later and see appear in other views?
}
class TestObject: ObservableObject {
@Published var elements: [TestModel] = [
TestModel(id: 1, name: "Element 1"),
TestModel(id: 2, name: "Element 2"),
TestModel(id: 3, name: "Element 3")
]
}
struct MyList: View {
@StateObject var testObject = TestObject()
@State var presenting = false
@State var tappedId: Int?
var body: some View {
List(testObject.elements) { element in
Text(element.name)
.onTapGesture {
tappedId = element.id
presenting = true
}
}
.modifier(
MyViewModifier(presented: $presenting, tappedId: tappedId)
// .environmentObject(testObject) ?
)
}
}
struct MyViewModifier: ViewModifier {
@Binding var presented: Bool
var tappedId: Int?
@EnvironmentObject var testObject: TestObject
func body(content: Content) -> some View {
content.overlay(
ZStack {
if presented {
MyView(testObject: _testObject, tappedId: tappedId)
}
}
)
}
}
struct MyView: View {
@EnvironmentObject var testObject: TestObject
var tappedId: Int?
var body: some View {
ZStack {
Color.white
Text(testObject.elements.first(where: { $0.id == tappedId })?.name ?? "-")
}
.frame(width: 250, height: 250)
}
}当然,当试图显示TestView时,这会引发错误:
未发现
ObservableObject型TestObject。作为此视图的祖先,可能缺少用于View.environmentObject(_:)的TestObject。
(FYI我想使用一个环境对象并将它传递给修饰符的原因,然后视图是,当TestView中的API出现在屏幕上时,我可能想调用它,这将获取这个对象的更多信息,并在MyList和MyView中分派这些信息)
你在这里有什么建议?谢谢你的帮助。
发布于 2022-05-20 10:10:43
正如注释中所建议的那样,可以将对象作为参数传递给ViewModifier。
另一种选择是在.environmentObject()之后调用.modifier(),您应该能够从修饰符中读取该对象。
struct MyList: View {
@StateObject var testObject = TestObject()
@State var presenting = false
@State var tappedId: Int?
var body: some View {
List(testObject.elements) { element in
// blah blah
}
.modifier(MyViewModifier(presented: $presenting, tappedId: tappedId))
.environmentObject(testObject)
}
}https://stackoverflow.com/questions/72316922
复制相似问题