Swift中UICollectionView添加选中用户显示异常问题排查
问题:UICollectionView显示错误用户,无法正确展示选中的群组成员
我开发了一款群聊应用,可通过点击用户将其添加到群组中。群成员选择页面布局为顶部是UICollectionView,底部是UITableView。点击任意用户行时,该用户应被添加到顶部的UICollectionView中,但目前存在bug:无论点击第二行(tester 2)还是第三行(apple),UICollectionView始终依次显示第一个用户、第二个用户等,而非实际选中的用户。
相关代码
UICollectionView 代码
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return chosenUser.count } func updateCollectionView() { DispatchQueue.main.async { self.collectionView.reloadData() } } var chosenUser: [User] = [] func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as! ChosenUserCollectionViewCell let user = users[indexPath.row] cell.chosenUserImage.layer.cornerRadius = 30 cell.chosenUserImage.layer.masksToBounds = true cell.chosenUserImage.contentMode = .scaleAspectFill if let profileImageUrl = user.profileImageUrl { cell.chosenUserImage.loadImageUsingCacheWithUrlString(profileImageUrl) } else { cell.chosenUserImage.image = UIImage(named: "profileIcon") } return cell } // 重复实现的方法,建议删除其中一个 func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return chosenUser.count }
UITableView 代码
protocol toRefresh { func updateCollectionView() } func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { let user = users[indexPath.row] self.chosenUser.append(user) updateCollectionView() }
问题分析与解决方案
你的tableView(_:didSelectRowAt:)方法本身没有错误——它确实把选中的用户正确添加到了chosenUser数组中。问题出在UICollectionView的cellForItemAt方法里:
你在获取要显示的用户数据时,用的是users[indexPath.row](原始用户列表数组),而不是chosenUser[indexPath.row](你选中的用户数组)!这就导致不管你往chosenUser里添加了哪些用户,CollectionView始终从原始的users数组按顺序取第N个元素,自然永远显示前几个用户,而非你实际选中的。
修正后的UICollectionView cellForItemAt方法
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as! ChosenUserCollectionViewCell // 改成从选中的用户数组取数据 let user = chosenUser[indexPath.row] cell.chosenUserImage.layer.cornerRadius = 30 cell.chosenUserImage.layer.masksToBounds = true cell.chosenUserImage.contentMode = .scaleAspectFill if let profileImageUrl = user.profileImageUrl { cell.chosenUserImage.loadImageUsingCacheWithUrlString(profileImageUrl) } else { cell.chosenUserImage.image = UIImage(named: "profileIcon") } return cell }
另外,你还重复实现了collectionView(_:numberOfItemsInSection:)方法,建议删除其中一个,避免后续维护出现混淆。
额外验证步骤
如果修正后还是有问题,可以在tableView(_:didSelectRowAt:)里添加打印语句,确认chosenUser数组确实正确添加了选中的用户:
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { let user = users[indexPath.row] self.chosenUser.append(user) // 打印验证选中逻辑是否正常 print("选中用户:\(user),当前已选列表:\(chosenUser)") updateCollectionView() }
内容的提问来源于stack exchange,提问作者William Loke
相关产品推荐
相关产品推荐

