Button on collection view cell does not react to events - ios

I have a UICollectionViewCell subclass, and a corresponding .xib file associated with it. The cell has some labels and a button with an action attached to it.
The problem is when I tap that button, only:
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{/*...*/}
gets called.
I guess there should be some way to change the tap event down the chain.
Did anyone face these issues before?
If yes, how did you solve this problem?

I've encountered this issue before when the button isn't in a Collection View Cell in the .xib. If you just have it in a view it won't be in the contentView and won't respond appropriately to events.
Once you do that you should be able to create an IBAction in your UICollectionViewCell subclass and it will be hit.

How did you add the button, as a subview of of your UICollectionViewCell? You need to do that instead, and add a selector method to your UIButton rather than handling it in didSelectItemAtIndexPath:.
Here is an example:
In your - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath or in your custom cells class (Preferably due to efficiency),
Adding the button as a subview should appear as so:
self.icon = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[self.icon addTarget:self action:#selector(buttonTapped:) forControlEvents:UIControlEventTouchUpInside];
self.icon.frame = CGRectMake(-50, -50, 100, 100);
UIImage *image = [UIImage imageNamed:#"icon.png"];
[self.icon setImage:deleteImage forState:UIControlStateNormal];
if (ifYouNeedABOOL == YES) {
[cell addSubview:self.deleteIcon];
return cell;
}
You can then handle the tap event in your new selector method, buttonTapped:.
If you want to stick with adding it in Interface Builder using IBAction, you can utilize tags. Add them to the cells in cellForItemAtIndexPath:

Related

How can I select image through touch on tableviewcell

I am new to app development. In my app when I click on my table view cell, the cell is selected and didSelectRowAtIndexPath method is triggered irrespective of whether I clicked on image or cell. I want the image to be selected when I click on the image, not the cell. Thanks in advance.
Add UITapGestureRecognizer on your image view, and if you not want cell selection then off table view cell selection . on Tap function on image do what you want.
In your cellForRowAtIndexPath method, add a custom UIButton and assign the image as background image of the button. Then add target to the button and handle your code inside the button target method
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"CellIdentifier"];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"CellIdentifier"];
UIButton *imageButton = [[UIButton alloc] initWithFrame:<Give the frame you want>];
[imageButton setBackgroundImage:<your image> forState:UIControlStateNormal];
[imageButton addTarget:self action:#selector(imageButtonClicked:) forControlEvents:UIControlEventTouchUpInside];
[cell addSubview:imageButton];
}
return cell;
}
Here the best method is to create a custom UITableViewCell which have imageButton as an instance variable instead of creating it inside cellForRowAtIndexPath method. Now in the imageButtonClicked method
-(void)imageButtonClicked:(UIButton *)sender {
UIImage *image = sender.currentBackgroundImage;
//Do the logic what you want here
}
Please give the frame of the button so that it is placed at the position you want.
I haven't tried out this code. If sender.currentBackgroundImage is not giving you the image, then create a custom button extending from UIButton. The custom button should have a UIImage variable as an instance variable. Assign the variable to the image you want when it is initialized(in cellForRowAtIndexPath method). And then you can access the image in the button target method

cellForRowAtIndexPath method custom button show 2 time

I used this code in cellForRowAtIndexPath method. When I click on button or scroll table this button is shown two times. Why is this button shown 2 times please help me?
UIButton *trashbtn=[[UIButton alloc]initWithFrame:CGRectMake(cell.frame.size.width-20, cell.frame.size.height-30, 20, 20)];
[trashbtn setImage:[UIImage imageNamed:#"editor_trash"] forState:UIControlStateNormal];
[trashbtn addTarget:self action:#selector(DeleteMyAssociate:) forControlEvents:UIControlEventTouchUpInside];
[trashbtn setTag:indexPath.row];
[cell addSubview:trashbtn];
You should firstly add a UITableViewCell within your table in IB. Then give an identifier e.g. "MyCellIdentifier" to that cell. Still on IB, add your outlets, to that cell e.g. the button, the textFields... You can initially set the button to be invisible. Then in the method cellForRowAtIndexPath, you do:
- (UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"MyCellIdentifier"];
if(cell){
myButton.hidden = NO; //
myTextField.text = #"BlaBlaBla";
}
}
Hey I can give you a suggestion that use auto layout and storyboard to add button rather than adding it programmatically. That is more better and cleaner approach.
The problem you are facing is that cells are reused in tableviews, So the first time you create a button and add it to the cell, it appears once. But if it is dequeued, it already has the button, so when you add another one you end up with multiple buttons.
There are two ways to correct this.
Firstly, remove the button in the cell's prepareForReuse method, which is called just after the cell is reused.
Secondly, avoid creating custom views in the cellForTableView... method. Use a custom cell that already has the button. Now, you may ask, how do I hook up the action for the button if I do it this way? You can either provide a delegate method for your cell that calls back to your view controller, or you can pass your cell a block to perform when the button is clicked.
as far as i can get u already have a custom cell.. add a button to existing cell and create an IbOutlet for the same in customCell.h file
then in cellForRowAtIndexPath method access the button using its IBOutlet
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
customCell *cell =(customCell*) [tableView dequeueReusableCellWithIdentifier:#"customCell" forIndexPath:indexPath];
[cell.btn setTitle:#"blabla" forState:UIControlStateNormal];
[cell.btn setTag:indexPath.row];
[cell.btn addTarget:self action:#selector(method:) forControlEvents:UIControlEventTouchUpInside];
if(condition)
{
cell.btn.hidden=YES;
}
else
{
cell.btn.hidden = NO;
}
return cell;
}
Do not forget to register for the customCell class in your ViewController class
[tableName registerNib:[UINib nibWithNibName:#"customCell" bundle:nil] forCellReuseIdentifier:#"customCell"];
you can hide or unhide the button as per your requirements as well as add different actions to the button in each class.
Happy Coding..!!
Do vote it if my code was helpful for you.. ;)

IBAction for Buttons inside static Cell do not work with didSelectRowAtIndexPath is overrided

I have some static UITableViewCells. One of them with 5 buttons inside. Inside didSelectRowAtIndexPath I handle the selection event for all the cells except for the one with the buttons inside. The problem is the action for the buttons in that one cell does not work.
Any help will be appreciated.
Finally I figured out That the root of the problem was at a completely different area, heightForRowAtIndexPath was returning wrong height for that cell (actually smaller height),
So, the controller interpreted the touches to be in a completely different place than the actual place I was supposedly touching
You don't have the cellForAtIndexPath method, however you can implement the tableView:willDisplayCell:forRowAtIndexPath: method and add target for each button like so:
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
// get a reference to button
UIButton *button = (UIButton *)[cell viewWithTag:1];
[button addTarget:self action:#selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
}

how to detect a cell in uicollectionview didselect delegate method

I am building an app similar to iPhone photo app. I am able to show the images in a grid like view using PSUICollectionView. When I tap on a grid cell of collection view a checkbox image should appear. My problem is when I am using following code, I see that multiple random cells are being populated with check box images.
- (void)collectionView:(PSUICollectionView *)collectionView didSelectItemAtIndexPath: (NSIndexPath *)indexPath
{
NSLog(#"%# - %d", NSStringFromSelector(_cmd), indexPath.item);
ImageGridCell *cell = (ImageGridCell *)[collectionView cellForItemAtIndexPath:indexPath];
UIButton *chkboxBtn = [UIButton buttonWithType:UIButtonTypeCustom];
[chkboxBtn setFrame:CGRectMake(60, 60, 30, 30)];
[chkboxBtn setImage:[UIImage imageNamed:#"Checkmark-iPhone.png"] forState:UIControlStateNormal];
[cell addSubview:chkboxBtn];
}
The problem is likely your custom cell has not implemented the prepareForReuse method. As a cell is reused, it may or may not have the check box, depending on if the check box was added on a previous use.
Several ways to address this. One simple way is to add a tag to the ckhboxBtn, and then remove the chkboxBton in the prepareForReuse method. E.g., when adding the check box, add the following:
[chkboxBtn setTag:100];
Then in your UICollectionViewCell class implementation, add/expand the prepareForReuse method:
-(void)prepareForReuse{
[[self viewWithTag:100] removeFromSuperview];
}

UIButton in UITableView, selector applied on several buttons

I'm currently working in a UITableView, each cell containing a button with a specific UIImage in background. I'd like to change this image when the button is clicked in a cell.
I have this code, working perfectly but when I click on a button, several buttons are modified - every 5 buttons, don't know why. Here's the code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
[myCell.favorite addTarget:self action:#selector(pressed_fav:) forControlEvents:UIControlEventTouchUpInside];
return myCell;
}
- (void)pressed_fav:(id)sender
{
UIButton *myButton = sender;
[myButton setBackgroundImage:[UIImage imageNamed:#"star.png"] forState:UIControlStateNormal];
}
myCell is an instance of a customized cell, containing an IBOutlet 'favorite' pointing to the UIButton.
Its because UITableView re-uses cell.
You must have some logic in cellForRowAtIndexPath method to identify the image of a button.
Thank you so much guy !
Actually, when I delete the line:
myCell = [tableView dequeueReusableCellWithIdentifier:#"cinemaCell"];
It does not display the cell (it's well allocated and initialised instead).

Resources