UICollectionView 给出“索引超出范围”错误
Posted
技术标签:
【中文标题】UICollectionView 给出“索引超出范围”错误【英文标题】:UICollectionView gives "Index out of range" error 【发布时间】:2018-10-28 12:08:43 【问题描述】:这是一个问题。目前我想在 UITableView 中显示在数据库中注册的用户数的 UITableViewCell 。但是,它在 UITableViewDataSOurce 方法 (cellForItemAt) 中变为“索引超出范围”。 我理解错误的含义,但我不知道为什么会出现这样的错误。你能告诉我吗?
import UIKit
import Firebase
import FirebaseStorage
import FirebaseFirestore
import SDWebImage
struct MemberData
var image: URL?
var text: String?
class MemberSelectViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout
let statusBsr = UIApplication.shared.statusBarFrame.height
let db = Firestore.firestore()
var teamIDFromFirebase: String = ""
var fireAuthUID = (Auth.auth().currentUser?.uid ?? "no data")
var memberData = [MemberData]()
var memberImageArr = [Any]()
var memberTextArr = [Any]()
var memberUserIDArr = [Any]()
override func viewDidLoad()
super.viewDidLoad()
let collectionView = UICollectionView(frame: CGRect(x: 0, y: statusBsr, width: self.view.frame.width, height: self.view.frame.size.height - statusBsr), collectionViewLayout: UICollectionViewFlowLayout())
let nibName = UINib(nibName: "memberCollectionViewCell", bundle: nil)
collectionView.register(nibName, forCellWithReuseIdentifier: "memberCell")
collectionView.delegate = self
collectionView.dataSource = self
self.view.addSubview(collectionView)
getMemberData(collectionView: collectionView)
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
return 24
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize
let size = self.view.frame.size.width / 4
return CGSize(width: size, height: size)
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets
let inset = (self.view.frame.width / 4) / 5
return UIEdgeInsets(top: inset, left: inset, bottom: inset, right: inset)
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat
return (self.view.frame.width / 4) / 5
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "memberCell", for: indexPath) as! memberCollectionViewCell
let cellData = memberData[indexPath.row]
cell.memberImage.sd_setImage(with: cellData.image)
cell.memberTitle.text = cellData.text
return cell
private extension MemberSelectViewController
private func getMemberData(collectionView: UICollectionView)
self.db.collection("users").document(self.fireAuthUID).addSnapshotListener (snapshot3, error) in
guard let document3 = snapshot3 else
print("erorr2 \(String(describing: error))")
return
guard let data = document3.data() else return
self.teamIDFromFirebase = data["teamID"] as? String ?? ""
self.db.collection("users").whereField("teamID", isEqualTo: self.teamIDFromFirebase).getDocuments() (querySnapshot, err) in
if let err = err
print("Error getting documents: \(err)")
return
else
var i = 0
for document in querySnapshot!.documents
guard var documentData: [String: Any] = document.data() else return
self.memberImageArr.append((documentData["image"] as? String)!)
self.memberTextArr.append((documentData["name"] as? String)!)
self.memberData.append(MemberData(image: URL(string: self.memberImageArr[i] as! String), text: self.memberTextArr[i] as! String))
i += 1
【问题讨论】:
发布完整的日志,可能代码没有执行self.memberData.append()
let cellData = memberData [indexPath.row] ⇨ 线程1:致命错误:出现索引超出范围。
【参考方案1】:
在这个方法中
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
return 24
您通知集合视图将始终有 24 行,因此当视图加载时,它将开始在集合视图中获取 24 行的内容。
但是,您的 memberData
数组是这样定义的:
var memberData = [MemberData]()
意味着最初它是空的。
然后您开始在getMemberData
中向memberData
添加内容,但此时,您的集合视图可能已经开始填充并正在请求第 5 行的内容(例如)...在一个数组中没有元素,那会崩溃。
所以你可以做的是:
将numberOfItemsInSection
更改为不返回静态值,而是返回memberData
中的实际项目数,如下所示:
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
return memberData.count
在getMemberData
函数中将数据加载到memberData
后,您会告诉集合视图重新加载,它会再次运行构建集合视图的整个过程,这次是数据。
在cellForItemAt
中,您可以确保不要尝试获取不存在的内容:
if indexPath.row < memberData.count
let cellData = memberData[indexPath.row
//and so on
希望能给你一些线索。
【讨论】:
以上是关于UICollectionView 给出“索引超出范围”错误的主要内容,如果未能解决你的问题,请参考以下文章
monotouch UICollectionView 给出空引用错误
UICollectionView reloadData后cell被隐藏
UICollectionView didSelectItemAt 方法不起作用