Getting button action : UICollectionView Cell

28,070

Solution 1

I had this problem as well. No subviews would receive touch events. While Scott K's workaround does work, I still felt something was wrong. So I took another look at my nib, and noticed that the original subview I used to create a UICollectionViewCell was a UIView. Even though I changed the class to a subclass of UICollectionViewCell, XCode still considered it a UIView, and hence the issues you see with contentView not catching touch events.

To fix this, I redid the nib by making sure to drag a UICollectionViewCell object, and moving all the subviews to that. Afterwards, touch events began to work on my cell's subviews.

Could indicator to see if your nib is configured as a UICollectionViewCell is look at the icon for your high level view.

enter image description here

If it doesn't look like this, then its probably going to interpret touch events wrong.

Solution 2

When you create a UICollectionViewCell via a nib the contents of the nib are not added to the cell's contentView -- it all gets added directly to the UICollectionViewCell. There doesn't appear to be a way to get Interface Builder to recognize the top-level view in the nib as a UICollectionViewCell, so all of the contents inside 'automatically' get added to the contentView.

As sunkehappy pointed out, anything that you want to receive touch events needs to go into the contentView. It's already been created for you, so the best you can do is to programmatically move your UIButton into the contentView at awakeFromNib-time.

-(void)awakeFromNib {
    [self.contentView addSubview:self.myButton];
}

Solution 3

UICollectionViewCell Class Reference

To configure the appearance of your cell, add the views needed to present the data item’s content as subviews to the view in the contentView property. Do not directly add subviews to the cell itself. The cell manages multiple layers of content, of which the content view is only one. In addition to the content view, the cell manages two background views that are display the cell in its selected and unselected states.

You can add your button in awakeFromNib like this:

- (void)awakeFromNib
{
    UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 50, 50)];
    [button addTarget:self action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
    [self.contentView addSubview:button];
}

- (void)buttonClicked:(id)sender
{
    NSLog(@"button clicked");
}

Solution 4

I've just solved it with adding

[self bringSubviewToFront:myButton];

into awakeFromNib

Solution 5

I had a similar issue where subviews at the bottom part of the cell didn't receive touch events, but the top part was working fine. So I've started to investigate, and got the following results:

  • The interface builder will add any subviews of the cell you create in it to the contentView of the cell, even though the contentView itself is not visible in the interface builder
  • My code expanded the cells to suit the size of the content, so the majority of the cells in the collection view were of larger height than the blueprint in Interface Builder
  • For some reason, the 'Autoresize subviews' property of the cell itself was set to NO. This caused mysterious and not-visible-in-interface-builder contentView to remain of the same size as the cell had in interface builder originally, so any subviews that were outside the bounds of the contentView did not receive touches and were unresponsive

Setting the 'Autoresize subviews' of the cell in Interface Builder to YES solved my problem!

Share:
28,070

Related videos on Youtube

Lithu T.V
Author by

Lithu T.V

#CodeLover # An iOS/Swift developer by passion...Dealing with Software project management kinds of stuff Digital Media Platform SME #Techie #Pubg #Manga #NightOwl #Reader #Rider #shutterBug #songTracker #BingeWatcher #movieJunkie

Updated on December 06, 2020

Comments

  • Lithu T.V
    Lithu T.V over 3 years

    I have created a UICollectionViewCell by nib and added a button inside it and created a .h and .m files added the class to the nibs file's owner.then wrote a button action in the .m connected it via outlet.

    The collection view is populating fine ,but cannot get the buton action triggered. I think the delegate for collection cell is called.

    How can i get the button action?

  • sunkehappy
    sunkehappy over 11 years
    I'm not 100% sure whether we can do it via nib. I've tried but failed. Using the code in my answer works.
  • Deamon
    Deamon almost 11 years
    Works for me too. But I wonder if this breaks anything at all internally.
  • BastiBen
    BastiBen almost 11 years
    Migrated from PSTCollectionView to UICollectionView and had this problem.
  • Coach Roebuck
    Coach Roebuck over 10 years
    @haider: Thank you so much for providing this answer. I had organized my storyboard and nib in the same manner and experienced the same trouble. It is very easy to overlook something like this when a UIView is inserted to a new nib by default. I am very grateful for your answer.
  • Lukas Kalinski
    Lukas Kalinski about 10 years
    I don't know about previous versions, but in Xcode 5.1.1, creating a nib with a UICollectionViewCell as the root view element, will result in adding anything added to that root view to the contentView of the final cell once loaded. Thus, the part of this answer where it is stated that the contents of a nib will be added to the UICollectionViewCell instead of its contentView, is incorrect (at least for Xcode 5.1.1).
  • Bryan P
    Bryan P almost 10 years
    Is there a way to somehow implement the index path by using this solution?
  • Bryan P
    Bryan P almost 10 years
    Is there a way to somehow implement the index path by using this solution?
  • AJ9
    AJ9 almost 10 years
    This is also the case if a button is a subview on a UIView! Make sure the button is on the top level!
  • SeanR
    SeanR almost 10 years
    I already had "Autoresize subviews" set to YES, but your answer showed me that indeed my contentView wasn't being resized properly, and this was causing the problem. So now I need to figure out what other than "Autoresize subviews" could be causing this... EDIT: This answer solved it for me: stackoverflow.com/a/25774492/555807 Turns out it was the result of a bug in switching from Xcode 5 to Xcode 6.
  • Koen.
    Koen. over 9 years
    Great! I didn't want to apply all my constraints again so I fiddled with the xib file and converted it to a UICollectionViewCell without losing my constraints.
  • fatuhoku
    fatuhoku almost 9 years
    It's a bad idea to conflate -collectionView:didSelectItemAtIndexPath: with button presses, never mind having every cell know about its parent collection view
  • Rajesh Kumar
    Rajesh Kumar over 8 years
    Working fine. adding button custom view instead of cell content View.
  • Gregory Molette
    Gregory Molette over 8 years
    Thx Haider. You saved my day !
  • Medhi
    Medhi over 7 years
    It's not working but adding the target selector by code in awakeFromNib works perfectly.
  • gurooj
    gurooj over 7 years
    You are also creating a strong retain cycle between the cell and the collection view
  • Stephen Orr
    Stephen Orr almost 6 years
    @AJ9: Actually - A button inside a UIView is fine - SO LONG AS - the UIView has 'isUserInteractionEnabled = true'