【问题标题】:Multi-select List in SwiftUI+FirestoreSwiftUI+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,则可以跟踪它们。

标签: ios swift firebase google-cloud-firestore swiftui


【解决方案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)
        }
    }
}

【讨论】:

  • 谢谢!这一切都是有道理的,但是当我按照编写的代码输入时,我得到一个空白页,它似乎没有从数据库中提取任何项目
  • 没关系,搞定了,非常感谢!!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-13
  • 2021-09-02
  • 1970-01-01
  • 1970-01-01
  • 2021-02-04
  • 1970-01-01
相关资源
最近更新 更多