【发布时间】:2019-12-17 18:09:24
【问题描述】:
我正在尝试填充集合视图。当我在字典中使用一个值时,它显示为 nil,但是当我打印它时,它会在它为我提供字符串之前的行。
我之前修复了这个问题,但是当我重新制作我的收藏视图以解决我遇到的另一个错误时,这个错误又回来了。为了解决这个问题,我刚刚删除了 self.users.removeAll() 行。重新添加该行然后删除它这次不起作用。
我在这个函数中遇到了问题:
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionview.dequeueReusableCell(withReuseIdentifier: "userCell", for: indexPath) as! UserCell
print(user[indexPath.row].imagePath!)
cell.userImage.sd_setImage(with: URL(string: user[indexPath.row].imagePath!))
cell.nameLabel.text = user[indexPath.row].username
cell.userID = user[indexPath.row].userID
return cell
}
这里是完整的代码:
import UIKit
import Firebase
import SwiftKeychainWrapper
import SwiftUI
import FirebaseUI
class UserViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource {
@IBOutlet weak var collectionview: UICollectionView!
var user = [User]()
override func viewDidLoad() {
super.viewDidLoad()
collectionview.delegate = self
collectionview.dataSource = self
retrieveUsers()
}
func retrieveUsers() {
let ref = Database.database().reference()
ref.child("users/").observeSingleEvent(of:.value, with: { (snapshot) in
let users = snapshot.value as! [String : NSDictionary]
//self.user.removeAll()
for (_, value) in users {
if let uid = value["uid"] as? String {
if uid != Auth.auth().currentUser!.uid {
let userToShow = User()
if let username = value["username"] as? String, let imagePath = value["urlToImage"] as? String {
userToShow.username = username
userToShow.imagePath = imagePath
userToShow.userID = uid
self.user.append(userToShow)
print(userToShow)
}
}
}
}
self.collectionview.reloadData()
})
ref.removeAllObservers()
}
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionview.dequeueReusableCell(withReuseIdentifier: "userCell", for: indexPath) as! UserCell
print(user[indexPath.row].imagePath!)
cell.userImage.sd_setImage(with: URL(string: user[indexPath.row].imagePath!))
cell.nameLabel.text = user[indexPath.row].username
cell.userID = user[indexPath.row].userID
return cell
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return user.count //?? 0
}
func checkFollowing(indexPath: IndexPath) {
let uid = Auth.auth().currentUser!.uid
let ref = Database.database().reference()
ref.child("users").child(uid).child("following").queryOrderedByKey().observeSingleEvent(of: .value, with: { snapshot in
if let following = snapshot.value as? [String : AnyObject] {
for (_, value) in following {
if value as! String == self.user[indexPath.row].userID {
// self.tableview.cellForRow(at: indexPath)?.accessoryType = .checkmark
}
}
}
})
ref.removeAllObservers()
}
@IBAction func logOutPressed(_ sender: Any) {
KeychainWrapper.standard.removeObject(forKey:"uid")
do {
try Auth.auth().signOut()
} catch let signOutError as NSError{
print("Error signing out: %@", signOutError)
}
dismiss(animated: true, completion: nil)
}
}
extension UIImageView {
func downloadImage(from imgURL: String!) {
let url = URLRequest(url: URL(string: imgURL)!)
let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
if error != nil {
print(error!)
return
}
DispatchQueue.main.async {
self.image = UIImage(data: data!)
}
}
task.resume()
}
}
我没有正确填充字典吗?
另外,这里是 User 类:
import UIKit
class User: NSObject {
var userID: String?
var username: String?
var imagePath: String?
}
另外,这是用户字典在调试器中显示的内容:
【问题讨论】:
-
什么是
sd_setImage?如果它是异步的,那就是问题所在。你的代码没有按照你想象的顺序运行。 -
sd_setImage 是设置 ImageView 的函数。为什么 print 语句会打印一些东西,但紧随其后的行不起作用?异步真的那么不稳定吗?在我重新制作 collectionView 之前,同样的代码正在工作,所以我认为这是另外一回事,但我对 Xcode 太陌生,无法理解
-
因为后面的行并不是真正的后面。这就是异步的意思。
-
有没有办法确保该行在之后执行?据我了解,在我调用 reloadData() 之前,不应该格式化集合视图。在用户字典中的条目完成之前,我不会调用 reloadData()。如何确保在所有数据都存在之前不会形成单元格?
-
Nick,请学习了解异步数据处理的工作原理。请接受一些建议,例如在主线程上重新加载集合视图并使用非可选属性和初始化程序声明
User。如果他们对您有帮助,请考虑投票并接受答案。
标签: ios swift firebase firebase-realtime-database