ios - 自 Xcode 12 (Swift 5.3) 以来,嵌套集合视图不响应单元格选择
问题描述
由于最新的 xcode 更新(到版本 12),嵌套的委托方法didSelectItemAtUIColletionView
没有响应。
我的结构:(UITableView
垂直)- UITableViewCell
- UICollectionView
(水平)
垂直tableview
由三个部分组成。两节各只有一tableViewCell
节。这些中的每一个tableViewCells
都有一个水平的collectionView
。最后一部分有更多的 tableViewCells。
我只在第三部分使用 tableViews didSelectRowAt方法。对于第 1 节和第 2 节,我使用 collectionViews didSelectItemAt并通过 tableViewCell 发送回调。但didSelectItemAt不响应用户点击。
我不使用自定义选择方法。
在更新到 xcode 12 (swift 5.3) 之前,一切都按预期工作。
代码:
private lazy var tableView: UITableView = {
let tv = UITableView(frame: CGRect.zero, style: .grouped)
tv.translatesAutoresizingMaskIntoConstraints = false
tv.delegate = self
tv.dataSource = self
tv.register(FirstHeader.self, forHeaderFooterViewReuseIdentifier: FirstHeader.reuseIdentifier)
tv.register(SecondHeader.self, forHeaderFooterViewReuseIdentifier: SecondHeader.reuseIdentifier)
tv.register(FirstTVCell.self, forCellReuseIdentifier: FirstTVCell.reuseIdentifier)
tv.register(SecondTVCell.self, forCellReuseIdentifier: SecondTVCell.reuseIdentifier)
tv.register(ThirdTVCell.self, forCellReuseIdentifier: ThirdTVCell.reuseIdentifier)
tv.alwaysBounceVertical = true
tv.isDirectionalLockEnabled = true
return tv
}()
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
switch indexPath.section {
case 1:
guard let cell = tableView.dequeueReusableCell(withIdentifier: FirstTVCell.reuseIdentifier) as? FirstTVCell else { fatalError("Cant dequeue FirstTVCell") }
cell.setup(elements: firstElements, didSelect: onTap)
cell.selectionStyle = .none
return cell
case 2:...
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
switch indexPath.section {
case 3:
onCellTap?(thirdElements?[indexPath.row])
default:
return
}
}
tableViewCell
与代码collectionView
class FirstTVCell: UITableViewCell {
static let reuseIdentifier = "FirstTVCell"
private var didSelect: ((Element?) -> Void)?
private var elements: [Element]?
private lazy var collectionView: UICollectionView = {
let layout = UICollectionViewFlowLayout()
let cv = UICollectionView(frame: CGRect.zero, collectionViewLayout: layout)
cv.translatesAutoresizingMaskIntoConstraints = false
cv.delegate = self
cv.dataSource = self
cv.register(ChipCell.self, forCellWithReuseIdentifier: ChipCell.reuseIdentifier)
return cv
}()
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: .default, reuseIdentifier: reuseIdentifier)
addSubview(collectionView)
NSLayoutConstraint.activate([
collectionView.centerYAnchor.constraint(equalTo: centerYAnchor),
collectionView.centerXAnchor.constraint(equalTo: centerXAnchor),
collectionView.widthAnchor.constraint(equalTo: widthAnchor),
collectionView.heightAnchor.constraint(equalTo: heightAnchor)
])
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func setup(elements: [CoreElement]?, didSelect: ((CoreElement?) -> Void)?) {
self.didSelect = didSelect
self.elements = elements
collectionView.reloadData()
}}
extension ListChipCollectionCell: UICollectionViewDelegateFlowLayout, UICollectionViewDataSource {
...
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
didSelect?(elements?[indexPath.row])
}}
集合视图单元
class ChipCell: UICollectionViewCell {
static let reuseIdentifier = "ChipCell"
private let titleLabel: UILabel = {
let l = UILabel()
l.translatesAutoresizingMaskIntoConstraints = false
l.font = .customFont(of: .semiBold, size: 14)
l.textAlignment = .center
l.numberOfLines = 1
return l
}()
func setup(element: CoreElement?) {
titleLabel.text = element?.title
addSubview(titleLabel)
NSLayoutConstraint.activate([
titleLabel.centerYAnchor.constraint(equalTo: centerYAnchor),
titleLabel.centerXAnchor.constraint(equalTo: centerXAnchor),
titleLabel.widthAnchor.constraint(equalTo: widthAnchor, constant: -20)
])
}
}
解决方案
感谢@DonMag 的评论,我忘记在每个UITableViewCell
和UICollectionViewCell
他们的.contentView
.
而不是addSubview(collectionView)
使用contentView.addSubview(collectionView)
onUITableViewCell
前
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: .default, reuseIdentifier: reuseIdentifier)
backgroundColor = .black
addSubview(collectionView)
NSLayoutConstraint.activate([
collectionView.centerYAnchor.constraint(equalTo: centerYAnchor),
collectionView.centerXAnchor.constraint(equalTo: centerXAnchor),
collectionView.widthAnchor.constraint(equalTo: widthAnchor),
collectionView.heightAnchor.constraint(equalTo: heightAnchor)
])
}
后
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: .default, reuseIdentifier: reuseIdentifier)
backgroundColor = .black
contentView.addSubview(collectionView)
NSLayoutConstraint.activate([
collectionView.centerYAnchor.constraint(equalTo: centerYAnchor),
collectionView.centerXAnchor.constraint(equalTo: centerXAnchor),
collectionView.widthAnchor.constraint(equalTo: widthAnchor),
collectionView.heightAnchor.constraint(equalTo: heightAnchor)
])
}
推荐阅读
- docker - 使用 Klee docker 镜像时如何在 home/klee 下准备好源代码文件
- c# - 如果 Content-Type 为“text/plain”,则 GET RestSharp 请求返回空值,而如果 Content-Type 为“application/json”,则返回数据
- r - 使用 ggplot2 在 R 中绘制空间线
- wordpress - 我的 wordpress 网站不加载内容
- reactjs - Axios 有 CORS 问题
- django - 表单未显示 ValidationError
- ruby-on-rails - 如果使用 devise 出现错误,则将 css 类添加到输入
- wso2 - 从 DAS 升级 WSO2 SP
- android - React Native Navigation v1 安卓黑屏
- reactjs - 要使用 React,我应该使用 nodejs (express) 吗?