【问题标题】:retrieve information from firebase and set as an image and label in UICollectionView从 firebase 检索信息并在 UICollectionView 中设置为图像和标签
【发布时间】:2019-02-09 22:05:53
【问题描述】:

我正在尝试检索存储在 firebase 中的一些数据,并允许在集合视图中显示该信息。如profileImageUrl、姓名标签和电子邮件标签。

我曾尝试阅读 firebase 和 Apple 网站上的文档,但由于某种原因,我的代码返回纯文本。我没有收到任何错误,但我的代码没有按预期运行。当我转到我的应用程序的配置文件视图时,显示的唯一文本是我以编程方式放置的占位符。

let profileImageView: UIImageView = {
    let imageView = UIImageView()
    imageView.image = UIImage(named: "users")
    imageView.translatesAutoresizingMaskIntoConstraints = false
    imageView.contentMode = .scaleAspectFill
    return imageView
}()
let nameLabel: UILabel = {
 let label = UILabel()
    label.text = "User's Name"
    label.font = UIFont.boldSystemFont(ofSize: 18)
    label.textColor = GREEN_Theme
    return label
}()
let uidLabel: UILabel = {
    let label = UILabel()
    label.text = "User's uid"
    label.font = UIFont.boldSystemFont(ofSize: 16)
    label.textColor = GREEN_Theme
    return label
}()
let emailLabel: UILabel = {
    let label = UILabel()
    label.text = "User's email"
    label.font = UIFont.boldSystemFont(ofSize: 16)
    label.textColor = GREEN_Theme
    return label
}()
override init(frame: CGRect) {
    super.init(frame: frame)

    setupView()
}

func setupView() {
if Auth.auth().currentUser != nil {
    guard let uid = Auth.auth().currentUser?.uid else {
        return }
    Database.database().reference().child("users").child(uid).observeSingleEvent(of: .value, with: { (snapshot) in
        guard let dictionary = snapshot.value as? [String : Any] else {
            return }
       let user = CurrentUser(uid: uid, dictionary: dictionary)
        self.uidLabel.text = uid
        self.nameLabel.text = user.name
        self.emailLabel.text = user.email
       self.profileImageView.loadImageUsingCacheWithUrlString(user.profileImageUrl)
    }, withCancel: { (err) in
        print("attempting to load information")
      })  
       self.addSubview(profileImageView)
       self.addSubview(nameLabel)
       self.addSubview(emailLabel)
       self.addSubview(uidLabel)
     profileImageView.anchors(top: topAnchor, topPad: 125, bottom: bottomAnchor, bottomPad: 75, left: leftAnchor, leftPad: 20, right: rightAnchor, rightPad: 250, height: 20, width: 20)
    nameLabel.anchors(top: profileImageView.bottomAnchor, topPad: -50, bottom: bottomAnchor, bottomPad: 0, left: profileImageView.leftAnchor, leftPad: 0, right: rightAnchor, rightPad: 0, height: 20, width: 20)
    emailLabel.anchors(top: nameLabel.bottomAnchor, topPad: -80, bottom: bottomAnchor, bottomPad: 0, left: profileImageView.leftAnchor, leftPad: 0, right: rightAnchor, rightPad: 125, height: 20, width: 20)
    uidLabel.anchors(top: emailLabel.bottomAnchor, topPad: -40, bottom: bottomAnchor, bottomPad: 0, left: profileImageView.leftAnchor, leftPad: 0, right: rightAnchor, rightPad: 0, height: 20, width: 20)
    profileImageView.layer.zPosition = 10
    nameLabel.layer.zPosition = 10
    emailLabel.layer.zPosition = 10
    profileImageView.layer.borderWidth = 2.0
    profileImageView.layer.cornerRadius = 50
    profileImageView.layer.borderWidth = 2.0
    profileImageView.layer.borderColor = UIColor.white.cgColor
    profileImageView.layer.masksToBounds = true

 }
}

如果有人可以帮助批评我所拥有的东西,并帮助我展示正确的实现是什么样的,我将不胜感激。任何和所有的帮助将不胜感激

【问题讨论】:

    标签: swift firebase firebase-realtime-database uicollectionview


    【解决方案1】:

    有几处不正确。

    1. 您的单元不应该是负责下载或进行任何网络调用的单元,将其留给viewController 或者更好地为所有网络调用单独处理。
    2. Firebase 是异步的,因此在下载数据时,所有视图都已设置并显示,这就是为什么您只能看到占位符的原因。
    3. 检查选项有很多冗余代码,这不是什么大问题,但也不需要。

    您真的应该考虑更改所有这些代码并将不同的任务分离到不同的处理程序。例如,您可以创建一个单独的类来控制对 Firebase 的所有调用并返回带有完成块的值,从 viewController 或 collectionView 本身要求网络处理程序为您提供所需的数据,将此数据传递给单元格并让单元格显示数据,单元格应该只显示数据,而不是下载或请求网络请求。我无法为您编写一个完整的示例,但我认为如果您在 google 中四处逛逛,您会发现很多非常好的示例和教程。

    无论如何,只是为了让您入门,以便您查看代码中的错误,这里有一个快速修复它。即使它有效,也不要理所当然地认为一切都是固定的。您真的应该重构所有代码并分离不同的任务。希望这至少可以帮助您解决在单元格中显示下载数据的问题。

    let profileImageView: UIImageView = {
        let imageView = UIImageView()
        imageView.image = UIImage(named: "users")
        imageView.translatesAutoresizingMaskIntoConstraints = false
        imageView.contentMode = .scaleAspectFill
        return imageView
    }()
    let nameLabel: UILabel = {
        let label = UILabel()
        label.text = "User's Name"
        label.font = UIFont.boldSystemFont(ofSize: 18)
        label.textColor = GREEN_Theme
        return label
    }()
    let uidLabel: UILabel = {
        let label = UILabel()
        label.text = "User's uid"
        label.font = UIFont.boldSystemFont(ofSize: 16)
        label.textColor = GREEN_Theme
        return label
    }()
    let emailLabel: UILabel = {
        let label = UILabel()
        label.text = "User's email"
        label.font = UIFont.boldSystemFont(ofSize: 16)
        label.textColor = GREEN_Theme
        return label
    }()
    
    
    // Here you add a variable that is observed for SET, once a set happens bind() will be called and the views will be updated.
    var currentUser : CurrentUser? {
        didSet {
            self.bind()
        }
    }
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        //...
    }
    
    
    // setupView() should only add the UI appearance, and in this case it is calling firebase and setting currentUser, but it should not do that. This is what you have to refactor.
    func setupView() {
        self.addSubview(profileImageView)
        self.addSubview(nameLabel)
        self.addSubview(emailLabel)
        self.addSubview(uidLabel)
        profileImageView.anchors(top: topAnchor, topPad: 125, bottom: bottomAnchor, bottomPad: 75, left: leftAnchor, leftPad: 20, right: rightAnchor, rightPad: 250, height: 20, width: 20)
        nameLabel.anchors(top: profileImageView.bottomAnchor, topPad: -50, bottom: bottomAnchor, bottomPad: 0, left: profileImageView.leftAnchor, leftPad: 0, right: rightAnchor, rightPad: 0, height: 20, width: 20)
        emailLabel.anchors(top: nameLabel.bottomAnchor, topPad: -80, bottom: bottomAnchor, bottomPad: 0, left: profileImageView.leftAnchor, leftPad: 0, right: rightAnchor, rightPad: 125, height: 20, width: 20)
        uidLabel.anchors(top: emailLabel.bottomAnchor, topPad: -40, bottom: bottomAnchor, bottomPad: 0, left: profileImageView.leftAnchor, leftPad: 0, right: rightAnchor, rightPad: 0, height: 20, width: 20)
        profileImageView.layer.zPosition = 10
        nameLabel.layer.zPosition = 10
        emailLabel.layer.zPosition = 10
        profileImageView.layer.borderWidth = 2.0
        profileImageView.layer.cornerRadius = 50
        profileImageView.layer.borderWidth = 2.0
        profileImageView.layer.borderColor = UIColor.white.cgColor
        profileImageView.layer.masksToBounds = true
    
        guard let user = Auth.auth().currentUser else { return }
        let uid = user.uid
        let reference = Database.database().reference().child("users").child(uid)
        reference.observeSingleEvent(of: .value, with: { (snapshot) in
            guard let dictionary = snapshot.value as? [String : Any] else { return }
            self.currentUser = CurrentUser(uid: uid, dictionary: dictionary)
        }, withCancel: { (err) in
            print("attempting to load information")
        })
    }
    
    // This is the method that updates the cell views.
    func bind() {
        self.uidLabel.text = currentUser.uid
        self.nameLabel.text = currentUser.name
        self.emailLabel.text = currentUser.email
        self.profileImageView.loadImageUsingCacheWithUrlString(currentUser.profileImageUrl)
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-08-15
      • 2022-01-12
      • 1970-01-01
      • 2022-01-22
      • 1970-01-01
      • 1970-01-01
      • 2019-12-27
      • 1970-01-01
      相关资源
      最近更新 更多