自 Xcode 12 (Swift 5.3) 以来,嵌套集合视图不响应单元格选择
Posted
技术标签:
【中文标题】自 Xcode 12 (Swift 5.3) 以来,嵌套集合视图不响应单元格选择【英文标题】:Nested collection view doesn't respond on cell selection since Xcode 12 (Swift 5.3) 【发布时间】:2020-09-23 13:13:55 【问题描述】:由于最新的 xcode 更新(到版本 12),嵌套UIColletionView
的委托方法didSelectItemAt 没有响应。
我的结构: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])
CollectionViewCell
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)
])
【问题讨论】:
添加相关代码。 @PGDev 代码已添加。 @andre_hold - 你的ChipCell
类中的bgView
是什么?
@DonMag 是另一种观点。我已经缩短了代码 sn-p。我将在帖子中删除此内容
@andre_hold - 提示:当问题显示有点像我的代码时,很难修复代码。根据您所展示的内容,我怀疑问题出在您的 UITableViewCell
和 UICollectionViewCell
类中,看起来您正在将子视图直接添加到单元格本身。那是不行的。您应该将子视图添加到单元格的内置 .contentView
。
【参考方案1】:
感谢@DonMag 的评论,我忘记将每个UITableViewCell
和UICollectionViewCell
中的视图添加到他们的.contentView
。
在UITableViewCell
上使用contentView.addSubview(collectionView)
而不是addSubview(collectionView)
之前
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)
])
【讨论】:
【参考方案2】:如果您在单元格中使用addSubview
,则需要执行以下操作:
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?)
super.init(style: style, reuseIdentifier: reuseIdentifier)
contentView.isUserInteractionEnabled = true
【讨论】:
以上是关于自 Xcode 12 (Swift 5.3) 以来,嵌套集合视图不响应单元格选择的主要内容,如果未能解决你的问题,请参考以下文章
如何在 swift 5.3 中从 m4a 音频文件中获取 Track Id