skip to Main Content

I have a UICollectionView that appropriately recognizes taps on its cells in its collectionView(didSelectItemAt: ) delegate method.

However, I then embedded a collection view within the cell itself (so that each cell has its own collection view inside of it), but now the parent cell is not recognizing any taps anymore, I’m assuming because the embedded collection view is eating them up.

Is there some property that needs to be set so that the original (parent) cells register taps again even with their embedded collection views?

2

Answers


  1. This functionality can be confusing, as users are accustomed to "something else" happening when interacting with a control in a table view cell, rather than it selecting (or also selecting) the row itself.

    However, if you really want to do that…

    One approach is to use a closure in your cell. When you handle didSelectItemAt use the closure to tell the table view controller to select the row.

    Note that Apple’s docs point out:

    Note

    Selecting a row programmatically doesn’t call the delegate methods tableView(_:willSelectRowAt:) or tableView(_:didSelectRowAt:), nor does it send selectionDidChangeNotification notifications to observers.

    So, if you need to execute code when a table view row is selected, you’ll need to call that yourself – something like this:

    func myTableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        print("My didSelectRowAt:", indexPath)
    }
    

    Using the code in my answer to your previous question

    In SomeTableCell add this closure setup:

    public var didSelectClosure: ((UITableViewCell) ->())?
    

    and, still in SomeTableCell:

    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        print("collectionView didSelecteItemAt:", indexPath)
        print("Calling closure...")
        didSelectClosure?(self)
    }
    

    Next, in cellForRowAt in the table view controller, set the closure:

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "someTableCell", for: indexPath) as! SomeTableCell
        cell.rowTitleLabel.text = "Row (indexPath.row)"
        cell.thisData = myData[indexPath.row]
        
        cell.didSelectClosure = { [weak self] c in
            guard let self = self,
                  let idx = tableView.indexPath(for: c)
            else { return }
            // select the row
            tableView.selectRow(at: idx, animated: true, scrollPosition: .none)
            // that does not call didSelectRowAt, so call our own func
            //   if we want something to happen on row selection
            self.myTableView(tableView, didSelectRowAt: idx)
        }
        
        return cell
    }
    
    Login or Signup to reply.
  2. you can implement UICollectionViewDataSource & UICollectionViewDelegate methods of inner collectionViews inside the cells itself & pass the events with closure to main class with main UICollectionView.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search