8

I have a button in a custom cell of a collectionview. The collectionview is on a scrollview. For some reason, I am not able to click on the button. I've checked that all my elements have User Interaction enabled.

Here is my layout of the collection (I've hidden some sensitive data) enter image description here

Here is my custom collection view cell:

class MyCollectionViewCell: UICollectionViewCell {

    @IBOutlet weak var nameLabel: UILabel!
    @IBOutlet weak var connectButton: UIButton!

    var onConnectTap: (MyCollectionViewCell) -> Void)?
    @IBAction func connectButton(_ sender: Any) {
        onConnectTap?(self)
    }

    func populate(_ user: User) {
        nameLabel.text = user.name
     }
}

I have a xib file where a Touch Up Inside event of a button has been hooked up to the connectButton IBAction.

And in my ViewController:

MyCollectionView.register(UINib(nibName: "MyCollectionViewCell", bundle: nil), forCellWithReuseIdentifier: "cell") 

Here's my collection view function in my ViewController:

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

        let cell = myCollectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! MyCollectionViewCell
        let user = users.values[indexPath.row]
        cell.populate(user)

        cell.onConnectTap = { (cell) in
            //do something
        }

        return cell

}

Nothing happens when I click on the button. Am I missing something here? Is the scroll view interfering? Do I need to specifiy a addTarget? Or something else?

Prabhu
  • 12,995
  • 33
  • 127
  • 210
  • Is `connectButton` not called either? Have you hooked it up correctly in the interface builder? – luk2302 Apr 02 '18 at 17:14
  • It's not called, and yes I've double checked that it's hooked up correctly in IB. – Prabhu Apr 02 '18 at 17:16
  • create delegate method of button – Wings Apr 02 '18 at 17:30
  • 1
    You should try to set your collection view and its parent scroll view clipsToBounds attribute to `true`. Since your collection view is in a scroll view, the sizing of the scroll view can be challenging and maybe you can see the cell but the parent views don't have the right sizes, messing up the response chain. – Mick F Apr 02 '18 at 17:31
  • @DirtyHenry both alreayd have Clip To Bounds set to true in IB. – Prabhu Apr 03 '18 at 02:35
  • @Prabhu and have you checked that the frame/content sizes of both parents views were OK? – Mick F Apr 03 '18 at 10:57
  • Yes they seem to be fine – Prabhu Apr 06 '18 at 05:46

3 Answers3

27

After searching the entire web pretty much, I finally found the solution that was in the comment of this SO answer: https://stackoverflow.com/a/44908916/406322

I needed to add this in MyCollectionViewCell:

self.contentView.isUserInteractionEnabled = false

I think the cell selection was hijacking the touch event.

Prabhu
  • 12,995
  • 33
  • 127
  • 210
  • great worked for me, after trying whole day cell.contentView.isUserInteractionEnabled = false and public func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange) -> Bool { print(URL) return true } – Rajath Kornaya Sep 24 '18 at 18:42
  • Wow, that's super obscure. Great find! – brandonscript Mar 04 '19 at 03:52
  • If this solution worked for you, it's probably because in *MyCollectionViewCell* you are not properly adding your button as a subview (or subview of a subview) of `contentView`; you might be adding your button to the `view` instead. So the solution — instead of disabling interactions on `contentView`, you should be adding button to the `contentView` instead of the `view`. – Teng L Oct 23 '20 at 20:56
2

I'm facing the same issue and found the best solution after spending much time.

cell.contentView.isUserInteractionEnabled = false

But its the perfect solution, and adds only one line in the cell for item method

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

    let cell = myCollectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! MyCollectionViewCell

     cell.contentView.isUserInteractionEnabled = false
     return cell
}
pkamb
  • 33,281
  • 23
  • 160
  • 191
Maulik Patel
  • 2,045
  • 17
  • 24
0

Double-check the structure of the XIB file. I lost time dealing with this issue (where the button in the XIB did not seem to respond), as the structure had a second embedded cell, rather than just one (AboutCell in my case).

enter image description here

Claytog
  • 618
  • 8
  • 8