我目前正在尝试在不同的表格 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 提供以上代码。
最佳答案
您没有将数据加载到 SecondTableViewController
显示在屏幕上的实例,但显示为新的 SecondTableViewController
您在 func tableView(_:=,cellForRowAt:)
中创建的实例FirstTableViewController
中的方法.
日志是从您从中创建的多个实例打印出来的。
这不是您想要的,因为您正在创建多个 SecondTableViewController
每次在您的 FirstTableViewController
中显示新单元格时的实例.
您应该引用实际的 SecondTableViewController
呈现并提供数据。
如果您使用 Storyboard,您可以使用 prepare(for:sender:)
要做到这一点。
我们有两个选择:提供来自 FirstTableViewController
的全部数据至 SecondTableViewController
使用委托(delegate)设计模式,或者只提供 value
至 SecondTableViewController
并把它留给它。
根据您的代码,您可以只提供 SecondTableViewController
与 value
你的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
它的代表。
关于ios - Swift Tableview 从 Firebase 数据库加载数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57230555/