ios - Swift Tableview 从 Firebase 数据库加载数据

标签 ios swift firebase uitableview firebase-realtime-database

我目前正在尝试在不同的表格 View 中显示来 self 的 Firebase 实时数据库的数据。

在我的第一个 TableView 中,我加载了我的数据库结构的第一级(这已经有效)。

现在我想看看用户在第一个 tableview 中选择了什么,然后在一个新的 TableView 中显示我的数据库的下一级。

我的第二个 TableViewController.swift 文件中有一个函数,用于保存第一个 TableView 的选定行。

通过这种方式,我想将下一级从我的数据库保存到一个数组中,以便该数据将显示在我的第二个表格 View 中。当我随后调试我的新数组时,我还在新数组中看到了正确的数据。但是,数据没有显示在第二个 TableView 中。

我猜这是因为在 TableView 加载之前数据没有 100% 准备好。

你有什么建议吗?

Firebase 结构:

-sports
    -Bicycle
        -BMX
            -Bike 1
                -img: „bike1.png“
                -text: „bike 1“
            -Bike 2
                -img: „bike2.png“
                -text: „bike 1“
    -Car
        -Audi
            -Car 1
                -img: „car1.png“
                -text: „car 1“
            -Car 2
                -img: „car2.png“
                -text: „car 2“

FirstTableViewController:

import UIKit
import Firebase

class FirstTableViewController: UITableViewController {

    var categorie = [String]()

    func loadData() {
        var ref: DatabaseReference!
        ref = Database.database().reference()

        ref.child("sports").observeSingleEvent(of: .value, with: { snapshot in
            if let sports = snapshot.value as? [String: Any] {
                for (title, _) in sports {
                    self.categorie.append(title)
                    self.tableView.reloadData()
                }
            }
        })
    }

    override func viewDidLoad() {
        loadData()
        super.viewDidLoad()
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return categorie.count
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "sportCell")
        cell?.textLabel?.text = categorie[indexPath.row]
        return cell!
    }

    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        // Set the segue's identifier in the Storyboard
        performSegue(withIdentifier: "firstToSecond", sender: self)
    }

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "firstToSecond" {
            guard let destination = segue.destination as? SecondTableViewController,
                let indexPath = tableView.indexPathForSelectedRow else { return }
            destination.detailedValue = categorie[indexPath.row]
        }
    }
}

第二 TableView Controller :

import UIKit
import Firebase

class SecondTableViewController: UITableViewController {

    var detailedValue: String?
    var secondArray = [String]()

    func setIndex(value: String) {
        loadData(index: value)
    }

    func loadData(index: String) {
        var ref: DatabaseReference!
        ref = Database.database().reference()

        if (index != "") {
            ref.child("sports").child(index).observeSingleEvent(of: .value, with: { snapshot in
                if let sports = snapshot.value as? [String: Any] {
                    for (title, _) in sports {
                        self.secondArray.append(title)
                        self.tableView.reloadData()
                    }
                }
            })
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        if let detailedValue = detailedValue {
            loadData(index: detailedValue)
        }
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return secondArray.count
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "sorteCell")
        cell?.textLabel?.text = secondArray[indexPath.row]
        return cell!
    }
}

更新 1: 感谢@Jay Lee 提供以上代码。

更新 2: enter image description here

最佳答案

您没有将数据加载到 SecondTableViewController显示在屏幕上的实例,但显示为新的 SecondTableViewController您在 func tableView(_:=,cellForRowAt:) 中创建的实例FirstTableViewController 中的方法. 日志是从您从中创建的多个实例打印出来的。

这不是您想要的,因为您正在创建多个 SecondTableViewController每次在您的 FirstTableViewController 中显示新单元格时的实例. 您应该引用实际的 SecondTableViewController呈现并提供数据。

如果您使用 Storyboard,您可以使用 prepare(for:sender:)要做到这一点。 我们有两个选择:提供来自 FirstTableViewController 的全部数据至 SecondTableViewController使用委托(delegate)设计模式,或者只提供 valueSecondTableViewController并把它留给它。 根据您的代码,您可以只提供 SecondTableViewControllervalue你的setIndex(value:) SecondTableViewController 中的方法使用,并获取SecondTableViewController之后的数据负载。

例如,在您的 SecondTableViewController :

class SecondTableViewController: UITableViewController {
...
  var detailedValue: String?

  override func viewDidLoad() {
    super.viewDidLoad()
    if let detailedValue = detailedValue {
      setIndex(value: detailedValue)
    }
  }
...
}

在你的FirstTableViewController :

class FirstTableViewController: UITableViewController {
...
  override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    // Set the segue's identifier in the Storyboard
    performSegue(withIdentifier: "yourIdentifier", sender: self)
  }
...
  override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "yourIdentifier" {
      guard let destination = segue.destination as? SecondTableViewController,
            let indexPath = tableView.indexPathForSelectedRow else { return }
      destination.detailedValue = categories[indexPath.row]
    }
  }
}

但请注意,您已经有一个数据要显示在 SecondTableViewController 上在你的FirstTableViewController , 所以你应该制作一个 protocol并设置 FirstTableViewController它的代表。

编辑: 你的 segue 不应该像这样连接: wrong segue 但像这样: correct segue

关于ios - Swift Tableview 从 Firebase 数据库加载数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57230555/

相关文章:

ios - 具有多个部分的 UITableView 负载不稳定

ios - 更改 UILabel 文本仅适用于 viewDidLoad()

ios - 找不到占位符菜单

javascript - 返回在函数内部不起作用(快照)

firebase - recyclerview 的 onBindViewHolder 中的 Android Firebase 监听器

ios - UIAlertController 与 NSObject 重用次数更多

ios - iOS7无线上网/网络录音怎么访问?

ios - 如何检测月/年变化

database - Swift - Firebase 多个快照

ios - 第一次点击后表格 View 单元格被取消选择。