如何将 Firebase iOS 中的数据从 TableViewController 传递到另一个 ViewController
Posted
技术标签:
【中文标题】如何将 Firebase iOS 中的数据从 TableViewController 传递到另一个 ViewController【英文标题】:How pass data from Firebase iOS from a TableViewController to another ViewController 【发布时间】:2017-10-17 16:24:10 【问题描述】:我正在开发一个应用程序,当我试图通过在搜索栏中搜索期间从 Firebase 数据库中检索他们的昵称来查找用户时。我将所有用户昵称放在一个数组中,并在点击的文本与用户昵称与自动完成匹配时将其显示在 tableView 中。我能够做到。 但是现在我正在尝试显示用户个人资料页面,如果我搜索用户,我在表格视图中选择名称,然后在 tableView 上点击他的昵称,然后它打开另一个 ViewController 并应该显示所选用户的信息,但它只显示默认页面,没有关于所选用户的任何自定义信息。
我给你看我当前的代码:
class UserTableViewController: UITableViewController, UISearchResultsUpdating
var userTab = [String]()
var userEmpty = ["No user"]
var filteredUsers = [String]()
var searchController: UISearchController!
var resultsController = UITableViewController()
var name: String!
var ref: DatabaseReference!
var dictDetails: [String:AnyObject]?
override func viewDidLoad()
super.viewDidLoad()
self.resultsController.tableView.dataSource = self
self.resultsController.tableView.delegate = self
ref = Database.database().reference()
ref.child("users").queryOrdered(byChild: "pseudo").observeSingleEvent(of: .value, with: (snapshot) in
self.userTab = []
if (snapshot.value is NSNull)
print("No data found")
else
for child in snapshot.children
let userSnap = child as! DataSnapshot
let uid = userSnap.key
let userDict = userSnap.value as! [String: AnyObject]
let pseudo = userDict["pseudo"] as! String
let total = snapshot.childrenCount
self.userTab.append(pseudo)
self.resultsController.tableView.reloadData()
continue
)
self.searchController = UISearchController(searchResultsController: self.resultsController)
self.tableView.tableHeaderView = self.searchController.searchBar
self.searchController.searchResultsUpdater = self
self.searchController.dimsBackgroundDuringPresentation = false
self.definesPresentationContext = true
func updateSearchResults(for searchController: UISearchController)
self.filteredUsers = self.userTab.filter (user:String) -> Bool in
if user.lowercased().contains(self.searchController.searchBar.text!.lowercased())
return true
else
return false
self.resultsController.tableView.reloadData()
override func prepare(for segue: UIStoryboardSegue, sender: Any?)
if segue.identifier == "userProfil"
if let indexPath = self.tableView.indexPathForSelectedRow
let data = userTab[indexPath.row] as! [String: AnyObject]
let pseudo = data["pseudo"] as? String
let controller = segue.destination as! UserViewController
controller.pseudo = pseudo!
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
if tableView == self.tableView
return self.userTab.count
else
return self.filteredUsers.count
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
let cell = UITableViewCell()
if tableView == self.tableView
cell.textLabel?.text = self.userTab[indexPath.row]
else
cell.textLabel?.text = self.filteredUsers[indexPath.row]
return cell
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
performSegue(withIdentifier: "userProfil", sender: nil)
对于另一个视图控制器:
class UserViewController: UIViewController
@IBOutlet weak var name: UILabel!
var pseudo: String = ""
var dictionary: [String:AnyObject]?
var ref: DatabaseReference!
override func viewDidLoad()
super.viewDidLoad()
ref = Database.database().reference()
ref.child("users").queryOrdered(byChild: pseudo).observeSingleEvent(of: .value, with: (snapshot) in
if let dictionary = snapshot.value as? [String: AnyObject]
self.name.text = dictionary["pseudo"] as? String
)
我该怎么做?
【问题讨论】:
你调试的结果是什么?当您在回调中放置断点时,您可以从 firebase 打印数据? 好的,我解决了我的问题,我可以在这里发布解决方案 【参考方案1】:我自己解决了这个问题,如果它可以帮助其他人,我会发布代码。
我向你展示我当前的代码(第一个视图控制器是 UserTableViewController):
class UserTableViewController: UITableViewController, UISearchResultsUpdating
var userTab = [String]()
var userEmpty = ["No user"]
var filteredUsers = [String]()
var searchController: UISearchController!
var resultsController = UITableViewController()
var name: String!
var ref: DatabaseReference!
override func viewDidLoad()
super.viewDidLoad()
self.resultsController.tableView.dataSource = self
self.resultsController.tableView.delegate = self
ref = Database.database().reference()
ref.child("users").queryOrdered(byChild: "pseudo").observeSingleEvent(of: .value, with: (snapshot) in
self.userTab = []
if (snapshot.value is NSNull)
print("No data found")
else
for child in snapshot.children
let userSnap = child as! DataSnapshot
let uid = userSnap.key
let userDict = userSnap.value as! [String: AnyObject]
let pseudo = userDict["pseudo"] as! String
let total = snapshot.childrenCount
self.userTab.append(pseudo)
self.resultsController.tableView.reloadData()
continue
)
self.searchController = UISearchController(searchResultsController: self.resultsController)
self.tableView.tableHeaderView = self.searchController.searchBar
self.searchController.searchResultsUpdater = self
self.searchController.dimsBackgroundDuringPresentation = false
self.definesPresentationContext = true
func updateSearchResults(for searchController: UISearchController)
self.filteredUsers = self.userTab.filter (user:String) -> Bool in
if user.lowercased().contains(self.searchController.searchBar.text!.lowercased())
return true
else
return false
self.resultsController.tableView.reloadData()
// I change the content of this function
override func prepare(for segue: UIStoryboardSegue, sender: Any?)
if segue.identifier == "userProfil"
let userViewController = segue.destination as! UserViewController
userViewController.pseudo = self.name! // "name" is a String variable declared at the beginning, "pseudo" is a variable declared in the UserViewController
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
if tableView == self.tableView
return self.userTab.count
else
return self.filteredUsers.count
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
let cell = UITableViewCell()
if tableView == self.tableView
cell.textLabel?.text = self.userTab[indexPath.row]
else
cell.textLabel?.text = self.filteredUsers[indexPath.row]
return cell
// This function is the most important because after search a user in search bar, it display it in table view cell then you choose it so you go the UserViewController where you can see the username write on this user profile page, you got to write the performSegue at the end of this function if not it can't work because if you put the performSegue at the beginning it won't find the right username because the prepare for segue function will call before and we don't want our "name" variable is nil
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
let post = filteredUsers[indexPath.row] as! String
self.name = post
print("name : \(name!)") // You can see in the console the name of the user you choose
performSegue(withIdentifier: "userProfil", sender: nil)
对于另一个视图控制器(UserViewController):
class UserViewController: UIViewController
@IBOutlet weak var name: UILabel!
var pseudo = ""
override func viewDidLoad()
super.viewDidLoad()
name.text = pseudo // Here name is a Label, so I put the "pseudo" variable for display it in the "name" Label and it can show the right nickname of user you choose in the search bar
希望它可以帮助别人。 现在我正在尝试在同一页面中显示他的用户个人资料图片。
【讨论】:
以上是关于如何将 Firebase iOS 中的数据从 TableViewController 传递到另一个 ViewController的主要内容,如果未能解决你的问题,请参考以下文章
如何从Swift中的Cloud FireStore Firebase访问特定字段
如何按文档 ID 从 Firebase Firestore 获取数据 - iOS?
(iOS + Firebase)无法将图像从 UITableViewCell 传递给下一个 ViewController