如何将 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?

从firebase实时数据库IOS Swift中检索数据

将firebase数据添加到ios swift中的数组

(iOS + Firebase)无法将图像从 UITableViewCell 传递给下一个 ViewController

使用 AFNetworking 将 Firebase 通知从 ios 设备推送到花药