【问题标题】:Passing data from Firebase Database from UITableviewCell to next ViewController not showing将 Firebase 数据库中的数据从 UITableviewCell 传递到下一个 ViewController 未显示
【发布时间】:2019-09-09 22:09:39
【问题描述】:

我已经搜索了一些关于此问题的答案,但它们似乎都不适用于我的情况,这就是我决定询问社区的原因。我只是想将数据从表格视图单元格传递到下一个视图控制器。我已经能够准确地在我的单元格中显示信息,但是每当我选择行时,它只会显示没有信息的视图控制器

我尝试将标签和图片设置为 UITableViewCell 可能显示的任何内容,但它不起作用。我创建了一个定义变量的 NSObject 类,这就是为什么它让我对如何将数据传递到下一个视图控制器感到困惑。

这是我的 AddFriendViewController,我从 Firebase 获取用户并在 tableview 上显示我的信息

class AddFriendViewController: UIViewController {

var users = [Users]()


var databaseRef = Database.database().reference()


@IBOutlet weak var friendsTableView: UITableView!
override func viewDidLoad() {
    super.viewDidLoad()

    friendsTableView.delegate = self
    friendsTableView.dataSource = self

    fetchUser()

}

func fetchUser() {
    databaseRef.child("users").observe(.childAdded) { (snapshot) in
        if let dictionary = snapshot.value as? [String: AnyObject] {
            let user = Users()
            user.nameOfUser = dictionary["nameOfUser"] as? String ?? ""
            user.email = dictionary["email"] as? String ?? ""
            user.profileImageURL = dictionary["profileImageURL"] as? String ?? ""

            self.users.append(user)

            DispatchQueue.main.async {
                self.friendsTableView.reloadData()
            }
        }
    }

 }


}

extension AddFriendViewController: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

    return self.users.count
}

func numberOfSections(in tableView: UITableView) -> Int {
    return 1
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let friendCell = UITableViewCell(style: .subtitle, reuseIdentifier: "friendCell")


    let user = users[indexPath.row]
    friendCell.textLabel?.text = user.nameOfUser
    friendCell.detailTextLabel?.text = user.email


    if let profileImageURL = user.profileImageURL {
        let url = URL(string: profileImageURL)
        URLSession.shared.dataTask(with: url!) { (data, response, error) in
            if error != nil {
                print(error)
                return
            }
            DispatchQueue.main.async {

                friendCell.imageView?.image = UIImage(data: data!)

              }

            }.resume()
    }

    return friendCell

}

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

    performSegue(withIdentifier: "showFriendProfile", sender: self.users[indexPath.row])
    self.friendsTableView.deselectRow(at: indexPath as IndexPath, animated: true)
}

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "showFriendProfile" {
        if let indexPath = friendsTableView.indexPathForSelectedRow {
            let dvc = segue.destination as! DetailViewController

            ***This is where I am confused as to what I should be doing***
            //EDIT1: 
            print("The nameOfUser is \(user.nameOfUser!)")
            print("The email is \(user.email!)")

        }
    }
  }

}

这是我的用户类:

class Users: NSDictionary {
    var nameOfUser: String?
    var email: String?
    var profileImageURL: String?

}

这是我的 DetailViewController:

class DetailViewController: UIViewController {

var nameOfUser = String()
var email = String()
var profileImageURL = UIImage()

var ref: DatabaseReference?


@IBOutlet weak var profileImageView: UIImageView!

@IBOutlet weak var nameOfUserLabel: UILabel!
@IBOutlet weak var emailLabel: UILabel!

override func viewDidLoad() {
    super.viewDidLoad()
    nameOfUser = nameOfUserLabel.text!
    email = emailLabel.text!
    profileImageURL = profileImageView.image!

    }

}

显而易见的目标是简单地单击单元格以在下一个视图控制器上显示数据。我知道过去有人问过类似的问题,但我真的不知道如何使用这些问题来解决我的问题。任何帮助将不胜感激,如果有什么需要澄清的,请告诉我。

编辑1: 我在 prepare for segue 函数上添加了 print 语句,并注意到它至少在提取信息,但由于某种原因没有将其传递给下一个视图控制器。

谢谢

【问题讨论】:

    标签: ios swift firebase uitableview uiviewcontroller


    【解决方案1】:

    您只需要获取您的发件人并设置详细视图控制器的属性即可。

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "showFriendProfile" {
            guard let dvc = segue.destination as? DetailViewController else {
                return
            }
    
            if let user = sender as? Users {
                DispatchQueue.main.async {
                    dvc.nameOfUserLabel.text = user.nameOfUser
                    dvc.emailLabel.text = user.email
                    let url = URL(string: user.profileImageURL!)
                    let data = try? Data(contentsOf: url!)
                    dvc.profileImageView.image = UIImage(data: data!)
                }
            }
        }
    }
    

    【讨论】:

    • 感谢您的回复,但这不起作用。这仍然给了我标签和图像视图中包含的默认值。
    【解决方案2】:

    1- 发送对象(确保将 segue 源连接到 vc 本身而不是单元)

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
      if segue.identifier == "showFriendProfile" {
         if let indexPath = friendsTableView.indexPathForSelectedRow {
             let dvc = segue.destination as! DetailViewController
             dvc.user = sender as! Users
          }
       }
    } 
    
    class DetailViewController: UIViewController {
       var user:Users! // add this then inside viewDidLoad set the labels 
    }
    

    2- 不要在cellForRowAt 中使用URLSession.shared.dataTask(with: url!) { (data, response, error) 考虑使用SDWebImage

    import SDWebImage // install pods then add this line top of the vc
    
    friendCell.imageView?.sd_setImage(with: URL(string:urlStr), placeholderImage: UIImage(named: "placeholder.png"))
    

    3- 内部不需要DispatchQueue.main.async {

    DispatchQueue.main.async {
       self.friendsTableView.reloadData()
    }
    

    默认情况下,firebase 回调在主线程中运行

    【讨论】:

    • 我现在可以设置标签,但我不知道如何设置图像。
    猜你喜欢
    • 1970-01-01
    • 2018-09-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多