【问题标题】:SwiftUI Weird issue about ListSwiftUI 关于 List 的奇怪问题
【发布时间】:2021-06-09 13:48:24
【问题描述】:

首先让我展示示例代码:

复选框列表:

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

单个复选框:

 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)
        }
    }
}

数据:

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

.....

还有 CheckListItem:

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

我想很多人已经遇到过这个问题,假设您的复选框列表中有很多复选框足以滚动,您检查列表最前面的前 1 或 2 或几个,然后滚动到底部,再往回滚动,那些被选中的复选框被退回!

但是,今天早上我突然发现,如果你在 List 中使用 ForEach,那么一切正常:

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

谁能解释为什么会发生这个奇怪的问题以及为什么这种方法可以正常工作?谢谢。

【问题讨论】:

  • 这不是问题。视图在 List 中重复使用(就像在 UITableView 中一样),您必须在模型中保持选中状态,并且只在视图中显示它。

标签: ios swift swiftui swiftui-list


【解决方案1】:

正如@Asperi所提到的,List 就像在幕后的TableView。所以,Views 在离开屏幕时会被重用。 p>

要获得您想要的结果,您必须在模型类中保持选中/未选中状态。检查下面的代码。

 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"))
        }
    }
}

【讨论】:

    猜你喜欢
    • 2019-08-28
    • 2021-08-27
    • 2011-02-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-18
    • 2011-08-19
    相关资源
    最近更新 更多