当我在 iOS 14 上的 UITableView 单元格内使用 UICollectionView 时,UICollectionView cellForItemAt 未被调用
UICollectionView cellForItemAt not get called when I use a UICollectionView inside a UITableView cell on iOS 14
我知道这听起来很重复,并且有数百万个问题是这样问的,但是当我在 iOS 14 上的 tableView 单元格中使用 collectionView 时,不会调用 collectionView cellForItemAt 函数,它适用于 iOS 12.
I attached a demo project for it.
这是我的 tableView 单元格,里面有一个 collectionView:
class ServicesTableViewCell: UITableViewCell {
@IBOutlet weak var parentView: UIView!
@IBOutlet weak var collectionView: UICollectionView!
var items = [String]()
var data: ServiceRow?
override func awakeFromNib() {
super.awakeFromNib()
collectionView.frame.size = CGSize(width: screenWidth, height: 50)
collectionView.register(UINib(nibName: "ServiceFilterCell", bundle: Bundle.main), forCellWithReuseIdentifier: "ServiceFilterCell")
collectionView.delegate = self
collectionView.dataSource = self
collectionView.reloadData()
}
func fill(with data:ServiceRow) {
items = data.items?.compactMap({[=11=].name}) ?? []
parentView.backgroundColor = .clear
collectionView.reloadData()
}
}
extension ServicesTableViewCell: UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return items.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { // <= This guy is not called
let data = items[collectionView.tag]
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "ServiceFilterCell", for: indexPath) as! ServiceFilterCell
cell.fill(title: data, isSelected: false)
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: 80, height: 40)
}
}
这是我的 parent class tableView cellForRowAt:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "ServicesTableViewCell", for: indexPath) as! ServicesTableViewCell
cell.collectionView.tag = indexPath.section
cell.fill(with: services[indexPath.section])
cell.frame.size = CGSize(width: cell.frame.width, height: 50)
cell.collectionView.reloadData()
cell.layoutIfNeeded()
return cell
}
这里是 Tarun Tyagi 回答的截图:
最后,问题是 tableViewCell 的 xib 文件在我创建时符合 collectionViewCell,所以我创建了一个 tableViewCell,现在一切正常!
检查您的布局代码并确保 在 运行 时间 UICollectionView
具有非零尺寸(宽度和高度必须 > 0).
如果 width
/height
中的任何一个为零,它不需要显示任何内容,因此它不会调用 cellForItemAt:
的数据源实现。
您可以使用 View Hierarchy Debugger
在 运行 时间检查 UICollectionView
的 width
/height
值。
我知道这听起来很重复,并且有数百万个问题是这样问的,但是当我在 iOS 14 上的 tableView 单元格中使用 collectionView 时,不会调用 collectionView cellForItemAt 函数,它适用于 iOS 12.
I attached a demo project for it.
这是我的 tableView 单元格,里面有一个 collectionView:
class ServicesTableViewCell: UITableViewCell {
@IBOutlet weak var parentView: UIView!
@IBOutlet weak var collectionView: UICollectionView!
var items = [String]()
var data: ServiceRow?
override func awakeFromNib() {
super.awakeFromNib()
collectionView.frame.size = CGSize(width: screenWidth, height: 50)
collectionView.register(UINib(nibName: "ServiceFilterCell", bundle: Bundle.main), forCellWithReuseIdentifier: "ServiceFilterCell")
collectionView.delegate = self
collectionView.dataSource = self
collectionView.reloadData()
}
func fill(with data:ServiceRow) {
items = data.items?.compactMap({[=11=].name}) ?? []
parentView.backgroundColor = .clear
collectionView.reloadData()
}
}
extension ServicesTableViewCell: UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return items.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { // <= This guy is not called
let data = items[collectionView.tag]
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "ServiceFilterCell", for: indexPath) as! ServiceFilterCell
cell.fill(title: data, isSelected: false)
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: 80, height: 40)
}
}
这是我的 parent class tableView cellForRowAt:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "ServicesTableViewCell", for: indexPath) as! ServicesTableViewCell
cell.collectionView.tag = indexPath.section
cell.fill(with: services[indexPath.section])
cell.frame.size = CGSize(width: cell.frame.width, height: 50)
cell.collectionView.reloadData()
cell.layoutIfNeeded()
return cell
}
这里是 Tarun Tyagi 回答的截图:
最后,问题是 tableViewCell 的 xib 文件在我创建时符合 collectionViewCell,所以我创建了一个 tableViewCell,现在一切正常!
检查您的布局代码并确保 在 运行 时间 UICollectionView
具有非零尺寸(宽度和高度必须 > 0).
如果 width
/height
中的任何一个为零,它不需要显示任何内容,因此它不会调用 cellForItemAt:
的数据源实现。
您可以使用 View Hierarchy Debugger
在 运行 时间检查 UICollectionView
的 width
/height
值。