【问题标题】:How do I return TableView datasource values if I'm using Firebase/Firestore to query the returning value?如果我使用 Firebase/Firestore 查询返回值,如何返回 TableView 数据源值?
【发布时间】:2020-04-14 21:05:35
【问题描述】:

我了解 Firestore 是异步的。我只是在返回 cellForRowAtnumberOfRowsInSection 方法的值时遇到了一些麻烦。它没有返回任何单元格/行,因为返回在闭包之外,但我不能将返回放在闭包内。我该如何规避这个问题?

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    //Return the count how many workouts exist for each date.
    var counter = 0

    Firestore.firestore().collection("/users/\(self.userIdRef)/Days/\(dayIdArray[section])/Workouts/").getDocuments { (querySnapshot, error) in
        if error == nil && querySnapshot != nil {
            counter = querySnapshot?.count ?? 0
        }
    }
    return counter
}


override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCell(withIdentifier: self.cellID, for: indexPath)

    Firestore.firestore().collection("/users/\(self.userIdRef)/Days/\(dayIdArray[indexPath.section])/Workouts/").getDocuments { (querySnapshot, err) in

        if let err = err
        {
            print("Error getting documents: \(err)");
        }
        else
        {

            let firstValue = querySnapshot!.documents[indexPath.row]

            let myData = firstValue.data()
            let myDayRef = myData["workout"] as? String ?? ""
            cell.textLabel?.text = "\(myDayRef)"
            cell.textLabel?.textAlignment = .center
            cell.accessoryType = .disclosureIndicator
            cell.layer.backgroundColor = UIColor.clear.cgColor
            cell.textLabel?.textColor = UIColor(red: 0.1333, green: 0.2863, blue: 0.4, alpha: 1.0)
            cell.textLabel?.font = UIFont(name: "HelveticaNeue", size: 20)
        }
    }
    return cell
}

【问题讨论】:

  • 不要在 TableView 委托中调用 API。在 viewDidLoad() 或 viewDidAppear() 中调用 API 并创建数据数组。然后在 tableview 委托方法中使用该数据。
  • 关于如何查询这些值的任何提示?我知道我可能需要将值存储在字典中,因为我每天都有多个锻炼文档?

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


【解决方案1】:

您应该按照here 的说明在填充单元格后重新加载您的tableView。像这样的:

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCell(withIdentifier: self.cellID, for: indexPath)

    Firestore.firestore().collection("/users/\(self.userIdRef)/Days/\(dayIdArray[indexPath.section])/Workouts/").getDocuments { (querySnapshot, err) in

        if let err = err {

            print("Error getting documents: \(err)");

        } else {

            let firstValue = querySnapshot!.documents[indexPath.row]
            let myData = firstValue.data()
            let myDayRef = myData["workout"] as? String ?? ""

            cell.textLabel?.text = "\(myDayRef)"
            cell.textLabel?.textAlignment = .center
            cell.accessoryType = .disclosureIndicator
            cell.layer.backgroundColor = UIColor.clear.cgColor
            cell.textLabel?.textColor = UIColor(red: 0.1333, green: 0.2863, blue: 0.4, alpha: 1.0)
            cell.textLabel?.font = UIFont(name: "HelveticaNeue", size: 20)

            tableView.reloadData()
        }
    }
    return cell
}

注意tableView.reloadData()

【讨论】:

  • tableView(_:cellForRowAt:) 内部开始获取操作确实没有意义。通常,您希望获取viewDidAppear 上的数据并存储结果。然后,在收到(新)结果后,更新表格视图。
  • 同意,但这不是 OP 的要求。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-25
  • 2019-11-11
  • 1970-01-01
  • 2019-01-05
相关资源
最近更新 更多