繁体   English   中英

SwiftUI 关于列表的奇怪问题

[英]SwiftUI Weird issue about List

首先让我展示示例代码:

复选框列表:

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

......

和检查列表项:

   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)

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

在此处输入图像描述

正如@Asperi提到的, List就像幕后的TableView 。所以,当他们离开屏幕时, Views被重用。

要获得您想要的结果,您必须在 model class 中保持选中/未选中state。 检查下面的代码。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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