代码之家  ›  专栏  ›  技术社区  ›  Hans

具有@State属性的ForEach

  •  0
  • Hans  · 技术社区  · 6 年前

    我有一个 @State 属性(在示例中 @State var parent: Parent ),其中包含一个数组属性,我想在 ForEach

    ForEach(parent.children, id: \.self) { child in
        ChildView(child: child)
    }
    

    虽然我相信 $ 去召唤 correctly pass it to the child view . 但是我得到一个错误 Unable to infer complex closure return type; add explicit type to disambiguate .

    解决这个问题的正确方法是什么?为什么这个代码不正确?

    最小复制代码

    import UIKit
    import SwiftUI
    
    func setup() -> Parent {
        let child = Child(name: "foo")
        let parent = Parent(name: "bar")
        parent.children = [child]
        return parent
    }
    
    class Parent {
        var name: String
        var children: [Child] = []
    
        init(name: String) {
            self.name = name
        }
    }
    
    class Child: Hashable {
        static func == (lhs: Child, rhs: Child) -> Bool {
            lhs.name == rhs.name
        }
    
        func hash(into hasher: inout Hasher) {
            hasher.combine(self.name)
        }
    
        var name: String
    
        init(name: String) {
            self.name = name
        }
    }
    
    class SceneDelegate: UIResponder, UIWindowSceneDelegate {
        var window: UIWindow?
    
        func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
            let parent = setup()
            let parentView = ParentView(parent: parent)
    
            if let windowScene = scene as? UIWindowScene {
                let window = UIWindow(windowScene: windowScene)
                window.rootViewController = UIHostingController(rootView: parentView)
                self.window = window
                window.makeKeyAndVisible()
            }
        }
    }
    
    struct ChildView: View {
        @State var child: Child
    
        var body: some View {
            VStack {
                Text("Child “\(child.name)”")
            }
        }
    }
    
    struct ParentView: View {
        @State var parent: Parent
    
        var body: some View {
            VStack {
                Text("Parent “\(parent.name)”")
                // ForEach($parent.children, id: \.self) { child in
                // Yields error:
                // Unable to infer complex closure return type; add explicit type to disambiguate
                ForEach(parent.children, id: \.self) { child in
                    ChildView(child: child)
                }
            }
        }
    }
    
    struct ParentView_Previews: PreviewProvider {
        static var previews: some View {
            let parent = setup()
            return ParentView(parent: parent)
        }
    }
    
    0 回复  |  直到 6 年前
        1
  •  0
  •   mkowal87    6 年前

    我不知道你为什么需要这里的美元符号,但我会改变代码如下

    class Parent: ObservableObject {
        var name: String
        @Published
        var children: [Child] = []
    
        init(name: String) {
            self.name = name
        }
    }
    
    class Child: Hashable {
        static func == (lhs: Child, rhs: Child) -> Bool {
            lhs.name == rhs.name
        }
    
        func hash(into hasher: inout Hasher) {
            hasher.combine(self.name)
        }
    
        var name: String
    
        init(name: String) {
            self.name = name
        }
    }
    
    struct ChildView: View {
        @State var child: Child
    
        var body: some View {
            VStack {
                Text("Child “\(child.name)”")
            }
        }
    }
    
    struct ParentView: View {
        @ObservedObject
        var parent: Parent
    
        var body: some View {
            VStack {
                Text("Parent “\(parent.name)”")
                // ForEach($parent.children, id: \.self) { child in
                // Yields error:
                // Unable to infer complex closure return type; add explicit type to disambiguate
                ForEach(parent.children, id: \.self) { child in
                    ChildView(child: child)
                }
            }
        }
    }