SwiftUI:绑定 属性 不会更改视图

SwiftUI: Binded property does not change the views

我试图将 属性 绑定到 isFavorite,不知何故它的值在改变时改变但视图没有改变。

    @EnvironmentObject var modelData: ModelData
    var landmark:Landmark

    var landmarkIndex: Int {
        modelData.landmarks.firstIndex(where: { [=11=].id == landmark.id })!
    }
    
    var body: some View {
        ScrollView{
            MapPreview(coordinate: landmark.locationCoordinate)
                .ignoresSafeArea(edges: .top)
                .frame(height: 300)

            MapProfileImage(image: landmark.image)
                .offset(y: -130)
                .padding(.bottom, -130)
            
            VStack(alignment: .leading){
                HStack{
                    Text(landmark.name)
                        .font(.largeTitle)
                    FavoriteButton(isSet: $modelData.landmarks[landmarkIndex].isFavorite)
                }
                
                HStack{
                    Text(landmark.park)
                    Spacer()
                    Text(landmark.state)
                }

及其绑定到 属性 isSet

struct FavoriteButton: View {
    @Binding var isSet: Bool
    
    var body: some View {
        Button(action: {
            print("isSet \(String(isSet))")
            isSet.toggle()
            
        }){
            
            Image(systemName:isSet ? "star.fill" : "star")
                .foregroundColor(.black)
        }
    }
}

我是 SwitftUI 的新手,请注意解释有什么问题

通常使用 @Binding 来绑定父视图中的 @State 属性 和子视图中的另一个 属性。

在你的例子中,你已经在环境中有了你的视图模型,所以只需要在子视图中再次读取环境并直接在那里更改变量。

以下是您可以如何实施 FavoriteButton:

struct FavoriteButton: View {

    // Read the environment to get the view model
    @EnvironmentObject var modelData: ModelData

    // You will need to pass the index from the parent view
    let index: Int
    
    var body: some View {
        Button(action: {
            print("index \(index), isSet \(String(modelData.landmarks[index].isFavorite))")

            // Change the view model directly
            modelData.landmarks[index].isFavorite.toggle()
            
        }){
            
            Image(systemName: modelData.landmarks[index].isFavorite ? "star.fill" : "star")
                .foregroundColor(.black)
        }
    }
}

在父视图中,调用它传递索引:

FavoriteButton(index: landmarkIndex)

不用说了,ModelData需要是一个符合ObservableObjectclass,调用父视图时必须已经在环境中