自Xcode 12Swift 5.3起,嵌套集合视图对单元格选择不响应

问题描述

自从最新的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的{​​{1}}的代码

collectionView

CollectionViewCell

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])
}}

}

解决方法

由于@DonMag的评论,我忘记将UITableViewCellUICollectionViewCell中的视图添加到它们的.contentView中。

代替addSubview(collectionView)contentView.addSubview(collectionView)上使用UITableViewCell

之前

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: reuseIdentifier)
    
    backgroundColor = .black
    contentView.addSubview(collectionView)
    
    NSLayoutConstraint.activate([
        collectionView.centerYAnchor.constraint(equalTo: centerYAnchor),collectionView.heightAnchor.constraint(equalTo: heightAnchor)
    ])
}
,

如果您在单元格中使用//PropertiesService.getScriptProperties().setProperty('range',false); function partialDel() { var ss = SpreadsheetApp.getActiveSpreadsheet(); var sheet = ss.getSheetByName("UMS - Volumetria"); sheet.insertRowBefore(11); sheet.getRange(11,2).setValue("Item:"); sheet.insertRowBefore(13); sheet.getRange(13,2).setValue("Quantidade:"); sheet.getRange(13,6).setValue("de"); sheet.getRange("UMS - Volumetria!D13:E13").merge(); sheet.getRange("UMS - Volumetria!G13:H13").merge().setBorder(null,null,true,false,"black",SpreadsheetApp.BorderStyle.SOLID); PropertiesService.getScriptProperties().setProperty('range',true) } function addForm () { let range = "UMS - Volumetria!B9:L14" if(PropertiesService.getScriptProperties().getProperty('range')){ range = "UMS - Volumetria!B9:L16" } var ss = SpreadsheetApp.getActiveSpreadsheet(); const source = ss.getRange(range); const destSheet = ss.getSheetByName("UMS - Volumetria"); const destRange = destSheet.getRange(destSheet.getLastRow()+3,2); source.copyTo(destRange); } ,则需要执行以下操作:

addSubview