繁体   English   中英

从Firebase数据库加载Swift Tableview数据

[英]Swift Tableview Load Data from Firebase Database

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

在我的第一个表格视图中,我加载了数据库结构的第一级(这已经起作用了)。

现在,我想查看用户在第一个表格视图中选择的内容,然后在新的表格视图中显示数据库的下一层。

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

这样,我想将数据库中的下一个级别保存到数组中,以便此数据将显示在第二个表视图中。 然后,当我调试新阵列时,我还会在新阵列中看到正确的数据。 但是,数据不会显示在第二个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]
        }
    }
}

SecondTableViewController:

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: 在此处输入图片说明

你是不是将数据加载到SecondTableViewController被呈现在屏幕上的实例,而是一个新的SecondTableViewController您在创建的实例func tableView(_:=,cellForRowAt:)在你的方法FirstTableViewController 从您从中创建的多个实例中打印日志。

这不是您想要的,因为每次在FirstTableViewController显示一个新单元格时,您都将创建多个SecondTableViewController实例。 您应该获得对所显示的实际SecondTableViewController的引用,并SecondTableViewController提供数据。

如果您使用的是故事板,则可以使用prepare(for:sender:)进行操作。 我们有两个选择:使用委托设计模式将所有数据从FirstTableViewControllerSecondTableViewController ,或者仅将value提供给SecondTableViewController并保留取回信息。 基于您的代码,你可以提供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]
    }
  }
}

但是请注意,您已经有一个数据要显示在SecondTableViewControllerFirstTableViewController ,因此您可能应该制定一个protocol并将FirstTableViewController设置为其委托。

编辑:您的segue不应该这样连接: 错误的segue 但是像这样: 正确的选择

暂无
暂无

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

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