SwiftUI List does not updated when adding new item

Viewed 88

I have two columns with nested data(Parent/child). Each item in first column is parent. When selecting anyone of them then it shows its child in second column as list.

The problem is when adding data in parent list using button at top with add/update, then it refresh first column GUI immediately and shows updated data.

When adding data in second column using child add/update button then it not refresh 2nd column GUI immediately. Until I select the parent item from first column again then it shows updated data.

Here is my code and GUI screen shot

struct STClip: Identifiable, Hashable {
    
    var uid = UUID()
    var id :String
    var itemType:String?         // History or achive clips
    var clipTitle: String?       // Clip title
    var creationDate: Date?      // Clip Creation date
    var clipAttr:NSAttributedString?
}

struct STClipset: Identifiable, Hashable {
    
    var id = UUID()
    var clipsetName :String
    var isEditAble:Bool

    init( clipsetName:String, isEditAble:Bool){
        self.clipsetName = clipsetName
        self.isEditAble = isEditAble
    }
}

struct STClipItem: Identifiable, Hashable {
    var id = UUID()
    var clipsetObject: STClipset
    var clipObjects: [STClip]
}

class DictModel: ObservableObject {
    @Published var dict:[STClipItem] = []
    
    @Published var selectedItem: STClipItem? {
        didSet {
            if self.selectedItem != nil {
                //print("setitem did set is called")
                
                //if ( self.selectedItem?.clipObjects.count ?? 0 > 0) {
                  //  selectedItemClip = self.selectedItem?.clipObjects[0]
                //}
            }
        }
    }
    
    @Published var selectedItemClip: STClip? {
        didSet {
            if self.selectedItemClip != nil {
                //self.load(id: self.selectedItem!.itemId)
                //print("clipitem did set is called")
            }
        }
    }
}

struct TestPublishedDidSet: View {
    @ObservedObject var vm = DictModel()
    @State var selected:STClipItem? = nil
    @State var selectedClip:STClip? = nil
    @State var clipText = NSAttributedString(string: "Enter your text")
    
    var body: some View {
        VStack {
            //Button
            HStack{
                //Clipset button
                VStack{
                    Text("Add Parent data")
                        .padding(10)
                    
                    Button("Add") {
                        let clipset1 = STClipset(clipsetName: "Example clipset\(self.vm.dict.count)", isEditAble: false)
                        var clip1 = STClip(id: "0", itemType: "", clipTitle: "Clip 1")
                        clip1.clipAttr = NSAttributedString(string: clip1.clipTitle!)
                        clip1.creationDate = Date()
                        var clip2 = STClip(id: "1", itemType: "", clipTitle: "Clip 2")
                        clip2.clipAttr = NSAttributedString(string: clip2.clipTitle!)
                        clip2.creationDate = Date()
                        
                        let item = STClipItem(clipsetObject: clipset1, clipObjects: [clip1, clip2] )
                        self.vm.dict.append(item)
                    }
                    
                    Button("Update") {
                        let index = self.vm.dict.count - 1
                        self.vm.dict[index].clipsetObject.clipsetName = "Modifying"
                    }
                }
                
                Divider()
                //Clip button
                VStack{
                    Text("Add Child data")
                    .padding(10)
                    
                    Button("Add") {
                        
                        let object = self.vm.dict.firstIndex(of: self.vm.selectedItem!)
                        if( object != nil){
                            
                            let index = self.vm.selectedItem?.clipObjects.count
                            var clip1 = STClip(id: "\(index)", itemType: "", clipTitle: "Clip  \(index)")
                            clip1.clipAttr = NSAttributedString(string: clip1.clipTitle!)
                            clip1.creationDate = Date()
                            self.vm.dict[object!].clipObjects.append(clip1)
                        }
                    }
                    
                    Button("Update") {
                        let index = (self.vm.selectedItem?.clipObjects.count)! - 1
                        
                        self.vm.selectedItem?.clipObjects[index].clipAttr = NSAttributedString(string:"Modifying")
                        
                    }
                }
            }.frame(height: 100)
            
           
            //
            Divider()
            NavigationView{
                HStack{
                    
                    //Clipset list
                    List(selection: self.$vm.selectedItem){
                        ForEach(Array(self.vm.dict), id: \.self) { key in
                            Text("\(key.clipsetObject.clipsetName)...")
                        }
                    }
                    .frame(width:200)
                    .listStyle(SidebarListStyle())
                    
                    Divider()
                    VStack{
                        //Clip list
                        if(self.vm.selectedItem?.clipObjects.count ?? 0 > 0){
                            List(selection: self.$vm.selectedItemClip){
                                ForEach(self.vm.selectedItem!.clipObjects, id: \.self) { key in
                                    Text("\(key.clipTitle!)...")
                                }
                            }
                            .frame(minWidth:200)
                        }
                    }
                }
            }
        }
    }
}

Here is the screenshot:

enter image description here

1 Answers

I don't know it's a bug or anything else. These issues are solved by, reassigning the object to the selected item.

if( object != nil){
    
    let index = self.vm.selectedItem?.clipObjects.count
    var clip1 = STClip(id: "\(index)", itemType: "", clipTitle: "Clip  \(index)")
    clip1.clipAttr = NSAttributedString(string: clip1.clipTitle!)
    clip1.creationDate = Date()
    self.vm.dict[object!].clipObjects.append(clip1)
    self.vm.selectedItem = self.vm.dict[object!] //<<-- Here
}
Related