我遵循了1个教程,我能够使用一些数据(imageview和文本)填充collectionView:
let appleProducts = ["A", "B", "C", "D"]
let imageArray = [UIImage(named: "pug1"), UIImage(named: "pug2"), UIImage(named: "pug3"), UIImage(named: "pug4")]
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
{
return appleProducts.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
{
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath as IndexPath) as! CollectionViewCell
cell.imageView?.image = self.imageArray[indexPath.row]
cell.title?.text = self.appleProducts[indexPath.row]
return cell
}
现在从演示项目传递到我的,我想用FirebaseDatabse中的数据(图片和文本)填充这个CollectionView,所以我创建了这个方法:
struct item {
let pictureId: String!
let picture: String!
}
var items = [item]()
func getLatestAddedItems(){
self.items.removeAll()
let databaseRef = FIRDatabase.database().reference()
databaseRef.child("Items").observe(.value, with: {
snapshot in
//self.items.insert(item(picture: picture), at: 0)
for childSnap in snapshot.children.allObjects {
let snap = childSnap as! FIRDataSnapshot
//print(snap.key)
let picture = (snap.value as? NSDictionary)?["bookImage"] as? String ?? ""
//print(picture)
self.items.append(item(pictureId:snap.key, picture:picture))
}
print(self.items.count)
})
}
我创建此按钮以调用GetLatestAddedItems方法:
@IBAction func selectAction(_ sender: AnyObject) {
getLatestAddedItems()
}
这一个检查结果:
@IBAction func gettableAction(_ sender: AnyObject) {
print(self.items[0].picture)
print(self.items[1].picture)
print(self.items[2].picture)
print(self.items.count) }
OutPut结果:
picture 1 link
picture 2 link
picture 3 link
3
现在,在ContentView方法中进行必要的更改之后,Everythings看起来很好并且正确无误:
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
{
return items.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
{
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath as IndexPath) as! CollectionViewCell
//cell.imageView?.image = self.imageArray[indexPath.row]
let url = NSURL(string: items[indexPath.row].picture)
let data = NSData(contentsOf: url! as URL)
cell.imageView?.image = UIImage(data: data! as Data)
cell.title?.text = self.items[indexPath.row].pictureId
return cell
}
现在我得到一个空的ContentView,第一次使用按钮它是有效的,因为我调用getLatestAddedItems()将获取并向Items表添加数据,我尝试在ViewWillAppear或Viewdidload中调用它但是没有更改
这就是我认为return items.count返回0所以nothings会出现任何建议吗?
答案 0 :(得分:1)
将您的collectionView的协议委派初始化移至 ViewController生命周期范围之一,例如 viewDidLoad()
或< strong> viewWillAppear(_animated : Bool)
如果您正在使用自定义viewController(即在viewController中嵌入collectionView)
每次用户从数据库中收到值时重新加载collectionView。
override func viewDidLoad(){
super.viewDidLoad()
self.collectionView.dataSource = self
self.collectionView.delegate = self
}
func getLatestAddedItems(){
self.items.removeAll()
let databaseRef = FIRDatabase.database().reference()
databaseRef.child("Items").observe(.childAdded, with: {
snapshot in
for childSnap in snapshot.children.allObjects {
let snap = childSnap as! FIRDataSnapshot
let picture = (snap.value as? NSDictionary)?["bookImage"] as? String ?? ""
self.items.append(item(pictureId:snap.key, picture:picture))
print(self.items.count)
self.collectionView.reloadData()
}
})
}
PS: - 对firebase服务器的所有调用都是异步的,这需要一些时间从FBDB中检索数据,因此请print(self.items.count)
在firebase观察调用的 completionBlock 内部,否则如果它被放在外面,它甚至会在从FBDB检索到数据之前被调用。