简体   繁体   中英

SwiftUI Weird issue about List

First let me show the sample code:

checkboxlist:

    struct CheckListView: View {
    var body: some View {
        List(checkListData){ item in
            CheckView(isChecked: item.isChecked, title: item.title)
        }
        .font(.title)
    }
}

single checkbox:

 struct CheckView: View {
    @State var isChecked:Bool = false
    var title:String
    func toggle(){isChecked = !isChecked}
    var body: some View {
        HStack{
            Button(action: toggle) {
                Image(systemName: isChecked ? "checkmark.square" : "square")
            }
            Text(title)
        }
    }
}

the datas:

let checkListData = [
CheckListItem(id:0,title: "Neopolitan"),
CheckListItem(id:1,title: "New York"),
CheckListItem(id:2,title: "Hawaiian"),

.....

and the CheckListItem:

   struct CheckListItem:Identifiable{
    var id:Int
    var isChecked: Bool = false
    var title: String
}

I guess lots of guys already had this issue, suppose you have lots of checkboxes in you checkbox list which is enough to scroll, you check the first 1 or 2 or a few at the foremost of the list, then you scroll to the bottom, and scroll back again, those checked checkbox are turned back!

But, at this morning I suddenly found that if you use ForEach inside the List, then everything works fine:

List {
        ForEach(checkListData, id: \.id){ item in
            CheckView(isChecked: item.isChecked, title: item.title)
        }
    }.font(.title)

Can anyone explain why that weird issue happen and why this way is working fine? Thanks.

在此处输入图像描述

As @Asperi mentioned, List is just like TableView behind the scenes.So, Views are reused when they go off screen.

To get your desired result, you have to maintain checked/unchecked state in your model class. Check the code below.

 import SwiftUI

struct Test1: View {
    @ObservedObject var items = CheckListItem()
    
    var body: some View {
        CheckView(items: items)
    }
}

struct CheckView: View {
    @ObservedObject var items: CheckListItem
    
    var body: some View {
        List(0..<items.model.count) { i in
            HStack{
                Button {
                    items.model[i].isChecked = !items.model[i].isChecked
                } label: {
                    Image(systemName: items.model[i].isChecked ? "checkmark.square" : "square")
                }
                
                Text(items.model[i].title!)
            }
        }
    }
}

struct Model:Identifiable {
    var id:Int?
    var isChecked: Bool = false
    var title: String?
    
}

class CheckListItem:ObservableObject{
    @Published var model:[Model] = []
    
    init() {
        createObjects()
    }
    
    func createObjects() {
        for index in 0..<100{
            model.append(Model(id: index, isChecked: false, title: "Neopolitan"))
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM