English 中文(简体)
进口 阵列中的目标
原标题:SwiftUI Bind to @ObservableObject in array

How do I pass a bindable object into a view inside a ForEach loop?

最低再生产法如下。

class Person: Identifiable, ObservableObject {
    let id: UUID = UUID()
    @Published var healthy: Bool = true
}


class GroupOfPeople {
    let people: [Person] = [Person(), Person(), Person()]
}

public struct GroupListView: View {
    
    //MARK: Environment and StateObject properties
    
    //MARK: State and Binding properties
    
    //MARK: Other properties
    let group: GroupOfPeople = GroupOfPeople()
    
    //MARK: Body
    public var body: some View {
        ForEach(group.people) { person in
            //ERROR: Cannot find  $person  in scope
            PersonView(person: $person)
        }
    }
    
    //MARK: Init
    
}

public struct PersonView: View {
    
    //MARK: Environment and StateObject properties
    
    //MARK: State and Binding properties
    @Binding var person: Person
    //MARK: Other properties
    
    
    //MARK: Body
    public var body: some View {
        switch person.healthy {
        case true:
            Text("Healthy")
        case false:
            Text("Not Healthy")
        }
    }
    
    //MARK: Init
    init(person: Binding<Person>) {
        self._person = person
    }
}

我的错误是<代码>。 不能在范围找到人。 我的理解是,每座右翼的“inding”部分在“ForEach loop”执行期间就不属于适用范围。 我期待就一种不同模式提出建议,以在快速倡议清单中实现“具有约束力的反对”。

问题回答

快速 倡议方式类似:

// struct instead of class
struct Person: Identifiable {
    let id: UUID = UUID()
    var healthy: Bool = true
}


// class publishing an array of Person
class GroupOfPeople: ObservableObject {
    @Published var people: [Person] = [
        Person(), Person(), Person()
    ]
}

struct GroupListView: View {
    
    // instantiating the class
    @StateObject var group: GroupOfPeople = GroupOfPeople()
    
    var body: some View {
        List {
            // now you can use the $ init of ForEach
            ForEach($group.people) { $person in
                PersonView(person: $person)
            }
        }
    }
}

struct PersonView: View {
    
    @Binding var person: Person

    var body: some View {
        HStack {
            // ternary instead of switch
            Text(person.healthy ? "Healthy" : "Not Healthy")
            Spacer()
            // Button to change, so Binding makes some sense :)
            Button("change") {
                person.healthy.toggle()
            }
        }
    }
}

这里还有:

.onContinuousHover(perform: { phase in
    switch phase {
    case .active(let location):
        print(location.x)
    case .ended:
        print("ended")
    }
})




相关问题
List Contents of Directory in a UITableView

I am trying to list the contents of Ringtones directory in a TableView, however, I am only getting the last file in the directory in ALL cells, instead of file per cell. This is my code: - (...

iPhone NSUserDefaults persistance difficulty

In my app i have a bunch of data i store in the NSUserdefaults. This information consists of an NSObject (Object1) with NSStrings and NSNumbers and also 2 instances of yet another object (Object2). ...

Writing a masked image to disk as a PNG file

Basically I m downloading images off of a webserver and then caching them to the disk, but before I do so I want to mask them. I m using the masking code everyone seems to point at which can be found ...

Resize UIImage with aspect ratio?

I m using this code to resize an image on the iPhone: CGRect screenRect = CGRectMake(0, 0, 320.0, 480.0); UIGraphicsBeginImageContext(screenRect.size); [value drawInRect:screenRect blendMode:...

Allowing interaction with a UIView under another UIView

Is there a simple way of allowing interaction with a button in a UIView that lies under another UIView - where there are no actual objects from the top UIView on top of the button? For instance, ...

热门标签