Есть несколько вещей, которые не верны.
- ваша ячейка не должна отвечать за загрузку или выполнение каких-либо сетевых вызовов, оставьте это для
viewController
или, что еще лучше, отдельным обработчиком для всех сетевых вызовов. - Firebase является асинхронным, поэтому к моменту загрузки ваших данных все представления уже были настроены и отображены, поэтому вы видите только заполнители.
- У вас много избыточного кода для проверки дополнительных функций, это не является большой проблемой, но в этом нет необходимости.
Вы должны подумать об изменении всего этого кода и разделенииразные задачи для разных обработчиков.Например, вы можете создать отдельный класс, который контролирует все вызовы 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)
}