我有一个包含聊天室列表的表格视图,我试图获取每个单元格中所有成员的头像的集合视图。
正如我所知,我的函数获取有关房间成员的必要信息,并将其设置为a {
text-decoration: none !important;
box-shadow: none !important;
}
中的字典:
cellForRow
这是从Firebase获取数据的功能:
DispatchQueue.main.async {
self.getParticipantInfo(roomId: self.usersRooms[(indexPath as NSIndexPath).row].id)
existingRoomCell.avatarView.addSubview((self.navCollectionView?.view)!)
}
我看到每个字典中有5个打印到控制台(我目前有5个房间),所以看起来它为每个房间都有单独的字典。但是我不知道如何指定哪个词典属于哪个房间,所以只有那个房间的成员出现在相应的表格视图中。
例如,在集合视图的var avatarDictionary = NSMutableDictionary()
var statusDictionary = NSMutableDictionary()
func getParticipantInfo(roomId: String) {
let databaseRef = FIRDatabase.database().reference()
let groupRef = databaseRef.child("groups").child(roomId)
groupRef.observe(.childAdded, with: { snapshot in
if let snapDict = snapshot.value as? [String : AnyObject] {
for each in snapDict {
let uid = each.key
let avatar = each.value["profilePicture"] as! String
let status = each.value["status"] as! String
// Set those to the dictionaries [UID : value]
self.avatarDictionary.setValue(avatar, forKey: uid)
self.statusDictionary.setValue(status, forKey: uid)
DispatchQueue.main.async {
self.navCollectionView?.collectionView?.reloadData()
print("\n\nDone\n\n")
}
}
print("\n\navatarDictionary:\n \(self.avatarDictionary)")
print("\nstatusDictionary:\n \(self.statusDictionary)")
}
})
}
方法中,我通过将avatarDictionary中的所有值转换为数组来设置化身:
cellForItem
然而,由于我现在有多个词典,我不知道如何指定哪些词典适用于表格中的哪个房间。目前它只使用一个(我认为是第一个) DispatchQueue.main.async {
let avatars = self.roomVC?.avatarDictionary.allValues as! [String]
navBarCell.avatarImageView.loadImageUsingCacheWithUrlString(avatars[indexPath.row])
}
,因此化身只显示在表格中的一个房间。
如何让集合视图从正确的词典加载头像,而不仅仅是单个词典?
答案 0 :(得分:0)
由于Firebase调用是异步的,我建议将roomId
传递给您的tableviewcell并让单元格句柄加载头像和状态。
例如,一些伪代码:
class CustomCell: UITableViewCell {
var roomId:String? {
didSet {
if let roomId = roomId {
getParticipantInfo(roomId)
} else {
//clear the data and cancel any pending Firebase request
}
}
}
func getParticipantInfo(roomId: String) {
//load your room, parse the data into your dictionaries and use the dictionary to power the collectionview datasource
collectionView.reloadData()
}
func prepareForReuse() {
super.prepareForReuse()
roomId = nil
}
}
根据评论编辑
快速提问 - 您的问题提到TableView,变量是collectionView。解决方案并不重要,但它是哪一个?
我可以设想两种不同的方法来存储您的数据。您选择的内容取决于您的实际数据的外观。
如果每个房间的头像/状态都是唯一的,并且假设您只有一个部分,那么我们只需要关闭行。我会创建一个结构来保存您的数据,使一切更清晰。这里我有一个RowData结构数组,它包含roomId和一组Avatar结构,它们保存了imageURL和status。这样你就不会有两个平行的数组或明显相关信息的词典。如果我对这个假设错了,请纠正我。您现在可以使用行作为索引来访问头像数据。
struct Avatar {
var imageURL: String
var status: String //eventually this is better as an enum
}
struct RowData {
let roomId:String
var avatars = [Avatar]()
init(roomId: String) {
self.roomId = roomId
}
}
var rowData = [Int: RowData]()
func getParticipantInfo(roomId: String, row: Int) {
let databaseRef = FIRDatabase.database().reference()
let groupRef = databaseRef.child("groups").child(roomId)
var thisRow = RowData(roomId: roomId)
rowData[row] = thisRow
groupRef.observe(.childAdded, with: { snapshot in
if let snapDict = snapshot.value as? [String : AnyObject] {
for each in snapDict {
guard let imageURL = each.value["profilePicture"] as? String, let status = each.value["status"] as? String else { continue }
let avatar = Avatar(imageURL: imageURL, status: status)
thisRow.avatars.append(avatar)
}
DispatchQueue.main.async {
self.navCollectionView?.collectionView?.reloadItems(at:[IndexPath(section:0, row:row)])
print("\n\nDone\n\n")
}
}
})
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return rowData.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(forIndexPath: indexPath) as RoomCell
if let thisRowData = rowData[indexPath] {
cell.rowData = rowData[indexPath.row]
} else {
getParticipantInfo(roomId: usersRooms[indexPath.row].id, row: indexPath.row)
}
}
class RoomCell: UITableViewCell, UICollectionViewDataSource {
var collectionView:UICollectionView
var rowData:RowData? {
didSet {
collectionView.reloadData()
}
}
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return rowData ? rowData?.avatars.count : 0
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(for: indexPath)
let avatar = rowData?.avatars[indexPath.row]
}
}
或者,如果不同行中的头像之间存在大量重叠,您可以向“头像”结构添加类似var roomIds:[String]
的道具,并使用[Avatar]
数组,然后过滤roomId
填充您的行。此模型的优点是,如果您的API返回多行的头像信息,您实际上可以跨多行缓存数据而不会有重复的头像对象