SwiftUI+Firestore 中的多选列表

Posted

技术标签:

【中文标题】SwiftUI+Firestore 中的多选列表【英文标题】:Multi-select List in SwiftUI+Firestore 【发布时间】:2020-12-06 03:12:45 【问题描述】:

我正在尝试从 Firestore 加载集合列表,并让它们可以单独选择。我将它设置在从 Firestore 中拉入列表的位置,但如果我选择一个,它会选择全部。另外,我如何将这个数组拉到按钮的 VStack 中而不是列表中?在我的选择屏幕中,此列表有点位于页面中间,我宁愿使用按钮而不是列表,因为列表组件的大小不是动态的。

感谢帮助,代码如下!

import SwiftUI

struct FirestoreTest: View 
    
    @ObservedObject private var viewModel = TriggersViewModel()
    @State private var isSelected = false
    
    var body: some View 
        
        List(viewModel.triggers)  trigger in
            Button(action:  self.isSelected.toggle() ) 
                HStack 
                    if self.isSelected 
                    Text(trigger.name)
                        .foregroundColor(.white)
                        .font(.system(size: 16, weight: .bold))

                        Spacer()
                        Image(systemName: "checkmark")
                            .foregroundColor(Color(.systemPink))
                            .font(.system(size: 16))
                     else 
                        Text(trigger.name)
                            .foregroundColor(Color(.systemGray))
                            .font(.system(size: 16))
                    
                
                .padding(.vertical, 10)
            
        
        .onAppear() 
            self.viewModel.fetchData()
        
        
    

TriggerViewModel.swift

import SwiftUI
import FirebaseFirestore

class TriggersViewModel: ObservableObject 
    
    @Published var triggers = [Trigger]()
    
    private var db = Firestore.firestore()
    
    func fetchData() 
        db.collection("triggers").order(by: "name").addSnapshotListener  (querySnapshot, error) in
            guard let documents = querySnapshot?.documents else 
                print("No Documents")
                return
            
            
                self.triggers = documents.map  (queryDocumentSnapshot) -> Trigger in
                let data = queryDocumentSnapshot.data()
                
                let name = data["name"] as? String ?? ""
                
                return Trigger(name: name)
                
            
            
        
    

Trigger.swift

import SwiftUI

struct Trigger: Identifiable 
    var id: String = UUID().uuidString
    var name: String

【问题讨论】:

这是self.isSelected.toggle() 的问题,因为 isSelected 是视图的属性。因此,如果它设置为 true,那么它对于 if self.isSelected 的所有内容都设置为 true。您不想为选定的触发器将其设置为 true 吗?如果是这样,您需要向触发器添加一个属性以确定 OR,向视图添加一个属性以继续尝试选择哪些触发器 - 例如var selectedTriggers = [Trigger] 因此,如果您选择触发器 1、3 和 7,则可以跟踪它们。 【参考方案1】:

您需要将isSelected 移动到模型中,并将ForEach 用于VStack

这是可能的解决方案:

struct Trigger: Identifiable 
    var id: String = UUID().uuidString
    var name: String
    var isSelected = false

现在您可以删除@State private var isSelected = false,并且

VStack 
    ForEach(viewModel.triggers.indices, id: \.self)  i in
        Button(action:  viewModel.triggers[i].isSelected.toggle() ) 
            HStack 
                if viewModel.triggers[i].isSelected 
                Text(viewModel.triggers[i].name)
                    .foregroundColor(.white)
                    .font(.system(size: 16, weight: .bold))

                    Spacer()
                    Image(systemName: "checkmark")
                        .foregroundColor(Color(.systemPink))
                        .font(.system(size: 16))
                 else 
                    Text(viewModel.triggers[i].name)
                        .foregroundColor(Color(.systemGray))
                        .font(.system(size: 16))
                
            
            .padding(.vertical, 10)
        
    

【讨论】:

谢谢!这一切都是有道理的,但是当我按照编写的代码输入时,我得到一个空白页,它似乎没有从数据库中提取任何项目 没关系,搞定了,非常感谢!!

以上是关于SwiftUI+Firestore 中的多选列表的主要内容,如果未能解决你的问题,请参考以下文章

SwiftUI - 多选列表(不是自定义列表)

SwiftUI 2.0如何实现List整组或组内部分子项的多选功能

列表视图中的多选

如何从firestore中检索swiftUI中的预定义项目列表?

MVC 5下拉列表用于编辑视图中的多选值绑定

NetSuite Advanced PDF - 使用记录中的多选字段过滤项目表列表