[英]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提供了上面的代码。
你是不是将数据加载到SecondTableViewController
被呈现在屏幕上的实例,而是一个新的SecondTableViewController
您在创建的实例func tableView(_:=,cellForRowAt:)
在你的方法FirstTableViewController
。 从您从中创建的多个实例中打印日志。
这不是您想要的,因为每次在FirstTableViewController
显示一个新单元格时,您都将创建多个SecondTableViewController
实例。 您应该获得对所显示的实际SecondTableViewController
的引用,并SecondTableViewController
提供数据。
如果您使用的是故事板,则可以使用prepare(for:sender:)
进行操作。 我们有两个选择:使用委托设计模式将所有数据从FirstTableViewController
给SecondTableViewController
,或者仅将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
设置为其委托。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.