为什么模型更改时我的 SwiftUI 视图没有更新

时间:2021-06-02 16:41:47

标签: swift swiftui

如何更新列表中现有行的内容?

print 语句显示按钮正在更新 Bool,但视图没有更新。

内容(按钮)按预期移动,但操作和格式未按预期更改。

我正在使用的页面的代码:

struct NotificationView: View {
@ObservedObject  var notificationVModel: NotificationVModel = NotificationVModel()

var body: some View {
    NavigationView{
        List(notificationVModel.notificationarray,id:\.NotificationName){notificationVV in
            ZStack {
                if notificationVV.isShgowen {
                    Color (.green).opacity(0.1)
                        .cornerRadius(10)
                    
                }
                HStack{
                    Button(action: {
                        notificationVV.changTogle()
                        print("\(notificationVV.isShgowen)")
                        
                        
                    }, label: {
                        ZStack{
                            Circle()
                                .foregroundColor(Color(red: 0 / 255, green: 175 / 255, blue: 80 / 255))
                                .frame(width: 50, height: 50, alignment: .center)
                            Image(systemName: "bell")
                                .frame(width: 40, height: 40, alignment: .center)
                                .foregroundColor(.white)
                        }                            })
                    VStack{
                        HStack {
                            if notificationVV.isShgowen{
                                Text("true")
                                    .font(.custom("AvenirNext-DemiBold", size: 10))
                            }
                            Text(notificationVV.NotificationName)
                                .font(.custom("AvenirNext-DemiBold", size: 20))
                            Spacer()
                            Text(notificationVV.NotifivationDate)
                                .font(.custom("AvenirNext-Medium", size: 12))
                                .foregroundColor(.gray)
                        }.padding(.leading).padding(.trailing)
                        Text(notificationVV.NotificationDiscrip)
                            .font(.custom("AvenirNext-Regular", size: 11))
                            .lineLimit(nil)
                            .padding(.leading).padding(.trailing)
                    }
                }.padding()
            }
        }
       .navigationTitle("Notification")
        .navigationBarTitleDisplayMode(.inline)
    }
}

}

视图模型

class NotificationVModel: ObservableObject {

@Published var notificationarray : [NotificationV] = [
    NotificationV(NotificationName: "Notification 1", NotificationDiscrip: "Lorem ipsum dolor sit amet,consec tetur adipiscing elit Lorem ipsum doloramet,consec tetur adipiscing elit sit ipi piscing… ", NotifivationDate: "04/02/2021", isShgowen: false),        NotificationV(NotificationName: "Notification 2", NotificationDiscrip: "Lorem ipsum dolor sit amet,consec tetur adipiscing elit Lorem ipsum doloramet,consec tetur adipiscing elit sit ipi piscing… ", NotifivationDate: "05/03/2021", isShgowen: true),
]

}

模型

class NotificationV : ObservableObject{
let objectWillChange = ObservableObjectPublisher()
@Published var NotificationName : String = ""
@Published var NotificationDiscrip: String = ""
@Published var NotifivationDate:String = ""
@Published var isShgowen:Bool = false

init(NotificationName: String, NotificationDiscrip: String, NotifivationDate: String, isShgowen: Bool) {
        self.NotificationName = NotificationName
        self.NotificationDiscrip = NotificationDiscrip
        self.NotifivationDate = NotifivationDate
        self.isShgowen = isShgowen
    }

func changTogle(){
    if isShgowen == false {
        isShgowen = true
    }
}

}

1 个答案:

答案 0 :(得分:0)

  • NotificationV 使用 struct 而不是 class

  • 为按钮创建一个新视图,并将您的viewmodel模型发送到新的视图

  • 查找模型索引

欲了解更多信息,请阅读本教程

https://developer.apple.com/tutorials/swiftui/building-lists-and-navigation


struct NotificationView: View {
    @ObservedObject  var notificationVModel: NotificationVModel = NotificationVModel()
    
    var body: some View {
        NavigationView{
            List(notificationVModel.notificationarray,id:\.NotificationName){notificationVV in
                ZStack {
                    if notificationVV.isShowen {
                        Color (.green).opacity(0.1)
                            .cornerRadius(10)
                        
                    }
                    HStack{
                        ToggleNotification(notifications: $notificationVModel.notificationarray, notificationV: notificationVV)
                        VStack{
                            HStack {
                                Text(notificationVV.isShowen ? "true": "false")
                                if notificationVV.isShowen {
                                    Text("true")
                                        .font(.custom("AvenirNext-DemiBold", size: 10))
                                }
                                Text(notificationVV.NotificationName)
                                    .font(.custom("AvenirNext-DemiBold", size: 20))
                                Spacer()
                                Text(notificationVV.NotifivationDate)
                                    .font(.custom("AvenirNext-Medium", size: 12))
                                    .foregroundColor(.gray)
                            }.padding(.leading).padding(.trailing)
                            Text(notificationVV.NotificationDiscrip)
                                .font(.custom("AvenirNext-Regular", size: 11))
                                .lineLimit(nil)
                                .padding(.leading).padding(.trailing)
                        }
                    }.padding()
                }
            }
            .navigationTitle("Notification")
            .navigationBarTitleDisplayMode(.inline)
        }
    }
}


struct ToggleNotification:View {
    
    @Binding var notifications: [NotificationV]
    var notificationV: NotificationV
    
    var index:Int? {
        notifications.firstIndex { $0.NotificationName == notificationV.NotificationName}
    }
    
    var body: some View {
        Button(action: {
            notifications[index!].isShowen.toggle()
            print("\($notifications[index!].isShowen)")
 
        }, label: {
            ZStack{
                Circle()
                    .foregroundColor(Color(red: 0 / 255, green: 175 / 255, blue: 80 / 255))
                    .frame(width: 50, height: 50, alignment: .center)
                Image(systemName: "bell")
                    .frame(width: 40, height: 40, alignment: .center)
                    .foregroundColor(.white)
            }
            
        })
    }
}


struct NotificationV {
    var NotificationName : String = ""
    var NotificationDiscrip: String = ""
    var NotifivationDate:String = ""
    var isShowen:Bool = false
    
    init(NotificationName: String, NotificationDiscrip: String, NotifivationDate: String, isShowen: Bool) {
        self.NotificationName = NotificationName
        self.NotificationDiscrip = NotificationDiscrip
        self.NotifivationDate = NotifivationDate
        self.isShowen = isShowen
    }
}


class NotificationVModel: ObservableObject {
    
    @Published var notificationarray : [NotificationV] = [
        NotificationV(NotificationName: "Notification 1", NotificationDiscrip: "Lorem ipsum dolor sit amet,consec tetur adipiscing elit Lorem ipsum doloramet,consec tetur adipiscing elit sit ipi piscing… ", NotifivationDate: "04/02/2021", isShowen: false),        NotificationV(NotificationName: "Notification 2", NotificationDiscrip: "Lorem ipsum dolor sit amet,consec tetur adipiscing elit Lorem ipsum doloramet,consec tetur adipiscing elit sit ipi piscing… ", NotifivationDate: "05/03/2021", isShowen: true),
    ]
    
}

遵循大小写约定。类型和协议的名称是 UpperCamelCase。其他的都是小写的。

https://swift.org/documentation/api-design-guidelines/


更新

截至目前,NotificationV 必须是唯一的 NotificationName。无论如何,NotificationV 应确认 IdentifiableEquatable 协议并在 ToggleNotification

var index:Int? {
    notifications.firstIndex { $0 == notificationV}
}

通知V

struct NotificationV: Identifiable, Equatable {
    var id: UUID = UUID()
    var NotificationName : String = ""
    var NotificationDiscrip: String = ""
    var NotifivationDate:String = ""
    var isShowen:Bool = false
    
    init(NotificationName: String, NotificationDiscrip: String, NotifivationDate: String, isShowen: Bool) {
        self.NotificationName = NotificationName
        self.NotificationDiscrip = NotificationDiscrip
        self.NotifivationDate = NotifivationDate
        self.isShowen = isShowen
    }
}

这样做您总能找到正确的NotificationV,即使它们没有唯一的名称。