首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SwiftUI:@EnvironmentObject with ViewModifier?

SwiftUI:@EnvironmentObject with ViewModifier?
EN

Stack Overflow用户
提问于 2022-05-20 09:54:06
回答 1查看 116关注 0票数 0

下面是我想要做的事情的想法:我的应用程序的导航包含一个列表,它在点击手势上显示一个视图,这个视图由ViewModifier触发来执行动画。

简而言之:

MyList > MyViewModifier > MyView

由于我想将一些数据从列表传递到这个层次结构中的最终视图,所以我考虑使用@StateObject/@EnvironmentObject属性包装器。但我刚刚意识到,我不能像对待视图那样,将.environmentObject(xx)传递给ViewModifier。

下面是我到目前为止掌握的代码:

代码语言:javascript
复制
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出现在屏幕上时,我可能想调用它,这将获取这个对象的更多信息,并在MyListMyView中分派这些信息)

你在这里有什么建议?谢谢你的帮助。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-05-20 10:10:43

正如注释中所建议的那样,可以将对象作为参数传递给ViewModifier

另一种选择是在.environmentObject()之后调用.modifier(),您应该能够从修饰符中读取该对象。

代码语言:javascript
复制
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)
    }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72316922

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档