自 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
    


tableViewCellcollectionView 的代码

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 - 提示:当问题显示有点像我的代码时,很难修复代码。根据您所展示的内容,我怀疑问题出在您的 UITableViewCellUICollectionViewCell 类中,看起来您正在将子视图直接添加到单元格本身。那是不行的。您应该将子视图添加到单元格的内置 .contentView 【参考方案1】:

感谢@DonMag 的评论,我忘记将每个UITableViewCellUICollectionViewCell 中的视图添加到他们的.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) 以来,嵌套集合视图不响应单元格选择的主要内容,如果未能解决你的问题,请参考以下文章

苹果发布Xcode 7.3,Swift更新至2.2版本

自XCode7更新以来在设备上启动应用程序时出现黑屏

如何在 swift 5.3 中从 m4a 音频文件中获取 Track Id

自 Xcode 9.2 更新以来,一个子视图中没有标签栏

无效的 Swift 支持 xcode 8 itunesconnect 问题

自 Xcode 13 / iOS15 以来,获取“公共数据库中不允许自定义区域”