didSelectRowAtIndexPath is not invoked to UIButton of cellForRowAtIndex - ios

I know that there are many duplicates here regarding this question but my requirement is that I added 2 UIButtons on one cell and both the buttons will open two different views. If I set the property userInteractionEnabled to YES, then it will not pic the 'finalID' from didSelectRowAtIndexPath from the below code.
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if(tableView == self.tableViewProject){
static NSString *cellId = #"attachmentCellId";
attachmentCell *cell = (attachmentCell *)[self.tableViewProject dequeueReusableCellWithIdentifier:cellId];
if(!cell)
{
if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"attachmentCell" owner:self options:Nil];
for(id object in nib)
{
if([object isKindOfClass:[attachmentCell class]])
{
cell = (attachmentCell *)object;
break;
}
}
UIButton *button;
button = [[UIButton alloc] initWithFrame:CGRectMake(162, 0, 75, 53)];
[button addTarget:self action:#selector(buttonClicked) forControlEvents:UIControlEventTouchUpInside];
button.userInteractionEnabled = YES;
//button.userInteractionEnabled = NO;
[cell.contentView addSubview:button];
UIButton *buttonAttach = [[UIButton alloc] initWithFrame:CGRectMake(245, 0, 75, 53)];
[buttonAttach addTarget:self action:#selector(buttonAttachClicked) forControlEvents:UIControlEventTouchUpInside];
buttonAttach.userInteractionEnabled = YES;
//buttonAttach.userInteractionEnabled = NO;
[cell.contentView addSubview:buttonAttach];
cell = [nib objectAtIndex:0];
SaveAttachment *attach = [array objectAtIndex:indexPath.row];
cell.name.text = attach.name;
cell.list.text = [NSString stringWithFormat:#"%d", attach.list];
cell.attachment.text = [NSString stringWithFormat:#"%d", attach.attachment];
cell.date.text = attach.date;
}
return cell;
}
And my DidSelectRowAtIndexPath is
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"Array == %#", anotherTempArray);
NSString *finalId = [NSString stringWithFormat:#"%#", [anotherTempArray objectAtIndex:indexPath.row]];
NSLog(#"final id for selected row = %#", finalId);
NSUserDefaults *defaultForFinalId = [NSUserDefaults standardUserDefaults];
NSString *setFinalId = finalId;
[defaultForFinalId setObject:setFinalId forKey:#"SETFINALID"];
if(tableView == self.tableViewProject)
{
[self buttonClicked];
//[self viewDidLoadForList];
}
if(tableView == self.tableViewAttachmentList)
{
[self buttonAttachClicked];
}
}

If you want to call the selector of UIButton inside cell, then what you dont need to use didSelectRowAtIndexPath method.
What you did was correct upto adding handler to UIButton. Now, remove your didSelectRowAtIndexPath code to button's click handler. Here is how you can get indexPath from the button click handler.
- (void)buttonClicked:(UIButton *)sender {
UITableViewCell *cell = (UITableViewCell*)sender.superview.superview; //Since you are adding to cell.contentView, navigate two levels to get cell object
NSIndexPath *indexPath = [tableView indexPathForCell:cell];
// Now you can do the code you put in didSelectRow here.
}
Hope this helps.

change your code for button selector
[button addTarget:self action:#selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside]; //add colon in selector buttonClicked
[buttonAttach addTarget:self action:#selector(buttonAttachClicked:) forControlEvents:UIControlEventTouchUpInside]; //add colon in selector buttonAttachClicked

If U use buttons than U don't need to use didSelectRowAtIndexPath. Set tags on buttons to match indexPath.row of the cell in cellForRowAtIndexPath... This way when U press the button in buttonAttachClicked or buttonClicked just check the senders tag and pull that cell from the UITableView
Use this code for cellForRowAtIndexPath
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if(tableView == self.tableViewProject){
static NSString *cellId = #"attachmentCellId";
attachmentCell *cell = (attachmentCell *)[self.tableViewProject dequeueReusableCellWithIdentifier:cellId];
if(!cell)
{
if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"attachmentCell" owner:self options:Nil];
for(id object in nib)
{
if([object isKindOfClass:[attachmentCell class]])
{
cell = (attachmentCell *)object;
break;
}
}
cell.button = [[UIButton alloc] initWithFrame:CGRectMake(162, 0, 75, 53)];
[cell.button addTarget:self action:#selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
[cell.contentView addSubview:cell.button];
cell.buttonAttach = [[UIButton alloc] initWithFrame:CGRectMake(245, 0, 75, 53)];
[cell.buttonAttach addTarget:self action:#selector(buttonAttachClicked:) forControlEvents:UIControlEventTouchUpInside];
[cell.contentView addSubview:cell.buttonAttach];
cell = [nib objectAtIndex:0];
}
SaveAttachment *attach = [array objectAtIndex:indexPath.row];
cell.name.text = attach.name;
cell.list.text = [NSString stringWithFormat:#"%d", attach.list];
cell.attachment.text = [NSString stringWithFormat:#"%d", attach.attachment];
cell.date.text = attach.date;
[cell.button setTag:indexPath.row];
[cell.buttonAttach setTag:indexPath.row];
return cell;
}

Related

checkBox action event in uitableviewcell

I am having custom-cell in which i put the UIButton as the CheckBox.
I want the array of selected checkBox indexPath in ViewController.
I am trying to set the UIButton Action event into the ViewController but it is not accessible. Here is my Code,
-(UITableViewCell *)tableView:(UITableView *)tableView1 cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
CustomTableViewCellSaveSearchTableViewCell *cell = [tableView1 dequeueReusableCellWithIdentifier:#"SaveSearchCell"];
if(!cell)
{
cell = [[[NSBundle mainBundle]loadNibNamed:#"CustomTableViewCellSaveSearchTableViewCell" owner:self options:nil]objectAtIndex:0];
}
[self setText:cell];
[cell.btnDelete addTarget:self action:#selector(btnClick:) forControlEvents:UIControlEventTouchUpInside];
cell.btnDelete.tag = indexPath.row;
return cell;
}
-(void)btnClick : (UIButton *)btn
{
// I Can't accaes this method.
}
How can i get this.
UITableViewCells have a state of their own to reflect if they are selected or not. You don't need a button in the cells (it is discouraged for UX reasons anyway). Check here for a tutorial.
Do according to these three floowing method.
- (void)viewDidLoad {
[super viewDidLoad];
chekMarkArray = [[NSMutableArray alloc]init];
int totalData = 10;
chekMarkArray=[[NSMutableArray alloc] initWithCapacity:totalData];
for (int i=0; i<totalData; i++) {
[chekMarkArray addObject:#(0)];
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
UIButton *testButton;
if (cell == nil ||1) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
testButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
testButton.frame = CGRectMake(100, 5,25, 25);
testButton.tag = indexPath.row;
BOOL selectindex = [[chekMarkArray objectAtIndex:indexPath.row] boolValue];
if (!selectindex) {
testButton.backgroundColor = [UIColor greenColor];
}else{
testButton.backgroundColor = [UIColor redColor];
}
[testButton addTarget:self action:#selector(DropDownPressed:) forControlEvents:UIControlEventTouchDown];
[cell addSubview:testButton];
}
return cell;
}
checked button action
-(void)btnClick : (UIButton *)btn
{
UIButton *button = (UIButton*)sender;
BOOL currentStatus = [[chekMarkArray objectAtIndex:button.tag] boolValue];
//deselect all selection
for (int i=0;i<chekMarkArray.count;i++) {
[chekMarkArray replaceObjectAtIndex:i withObject:#(0)];//comment this line for multiple selected button
}
//select current button
[chekMarkArray replaceObjectAtIndex:button.tag withObject:#(!currentStatus)];
[self.tableView reloadData];
}
You may use this code instead of button
first Alloc NsmutableArray in ViewDidLoad
and put an Button outside Tableview to complete your action.
then add
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
if(cell.accessoryType == UITableViewCellAccessoryNone) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
[selectedRowsArray addObject:[arrShareTickets objectAtIndex:indexPath.row]];
}
else {
cell.accessoryType = UITableViewCellAccessoryNone;
[selectedRowsArray removeObject:indexPath];
}
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}

How to change button background color which is added on table view cell when we tapped on it?

I have added one custom button on tableview cell and everything is ok.
But here my main requirement is when I click that button for the "first time" which is added on table view cell, then the button background color needs to change(to red) and when I click the second time the button, the previous color needs to be displayed(back to white)
My code:
#import "ViewController2.h"
#interface ViewController2 ()
{
NSArray * Mainarray;
UITableView * MaintableView;
UIImageView * accessoryView;
UIButton *button;
BOOL tapped;
}
#end
#implementation ViewController2
- (void)viewDidLoad
{
[super viewDidLoad];
tapped = NO;
Mainarray = [[NSArray alloc]initWithObjects:#"Ram",#"Rama",#"Rakesh",#"Ranjith", nil];
self.view.backgroundColor = [UIColor darkGrayColor];
MaintableView = [[UITableView alloc]init];
MaintableView.translatesAutoresizingMaskIntoConstraints = NO;
MaintableView.tableFooterView = [[UIView alloc] initWithFrame:CGRectZero];
MaintableView.dataSource=self;
MaintableView.delegate=self;
MaintableView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
[MaintableView registerClass:[UITableViewCell class] forCellReuseIdentifier:#"Cell"];
[self.view addSubview:MaintableView];
NSDictionary * views = NSDictionaryOfVariableBindings(MaintableView);
NSArray * horizentalConstraint = [NSLayoutConstraint constraintsWithVisualFormat:#"H:|-0-[MaintableView]-0-|" options:0 metrics:nil views:views];
NSArray * verticalConstraint = [NSLayoutConstraint constraintsWithVisualFormat:#"V:|-0-[MaintableView]-0-|"options:0 metrics:nil views:views];
[self.view addConstraints:horizentalConstraint];
[self.view addConstraints:verticalConstraint];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return Mainarray.count;
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
return 50;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *Cell = [MaintableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
if (Cell == nil)
{
Cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
Cell.textLabel.text = [Mainarray objectAtIndex:indexPath.row];
button=[UIButton buttonWithType:UIButtonTypeRoundedRect];
button.tag=indexPath.row;
[button addTarget:self
action:#selector(aMethod:) forControlEvents:UIControlEventTouchDown];
[button setTitle:#"" forState:UIControlStateNormal];
button.frame = CGRectMake(Cell.frame.size.width - 50, 10, 30, 30);
button.layer.cornerRadius = 60/2.0f;
button.layer.borderColor=[UIColor blackColor].CGColor;
button.backgroundColor = [UIColor whiteColor];
button.layer.borderWidth=2.0f;
//setting tag to button
button.tag=indexPath.row;
[Cell.contentView addSubview:button];
return Cell;
}
-(void)aMethod :(id)sender
{
CGPoint buttonPosition = [sender convertPoint:CGPointZero toView:MaintableView];
NSIndexPath *indexPath1 = [MaintableView indexPathForRowAtPoint:buttonPosition];
NSInteger variable = indexPath1.row;
NSLog(#"ok it is %ld",(long)variable);
if(button.tag == variable){
button.backgroundColor= tapped ? [UIColor whiteColor]:[UIColor redColor];
tapped = YES;
}
}
-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
if ([cell respondsToSelector:#selector(setSeparatorInset:)]) {
[cell setSeparatorInset:UIEdgeInsetsZero];
}
if ([cell respondsToSelector:#selector(setPreservesSuperviewLayoutMargins:)]) {
[cell setPreservesSuperviewLayoutMargins:NO];
}
if ([cell respondsToSelector:#selector(setLayoutMargins:)]) {
[cell setLayoutMargins:UIEdgeInsetsZero];
}
}
#end
You can create an array in which u can store selected buttons.
Example:
var selectedButtons: [Bool] = [Bool](count: N, repeatedValue: false)
In your cellForRowAtIndexPath:
if selectedButtons[indexPath.row] {
yourButton.backgroundColor = UIColor.redColor()
} else {
yourButton.backgroundColor = UIColor.whiteColor()
}
Then in your tableView didSelectRowAtIndexPath you can say:
selectedButtons[indexPath.row] = true
tableView.reloadData()
Sorry, my code is in Swift but it isn't hard to convert it to Obj-C.
Give your button a tag value in the cellForRowIndexpath method:
button.tag=indexPath.row;
and in your view did load, make the BOOL as a property in your .m file and make it accessible for the whole class
BOOL tapped =NO;
and then in your button action method:
-(IBAction)buttonMethod:(id)sender{
if(sender.tag==0){
button.backgroundColor= tapped ? [UIColor whiteColor]:[UIColor redColor];
tapped = !tapped;
}
}
Please try below code. Hope this is work for you.
-(void)aMethod:(id)sender
{
UIButton *btn = (UIButton *)sender;
if ([btn.backgroundColor isEqual:[UIColor redColor]]) {
btn.backgroundColor = [UIColor whiteColor];
}
else{
btn.backgroundColor = [UIColor redColor];
}
}
Thanks.. :)
I tried to get the solution for your question and finally i got.
First you have to change Button Type RECT to CUSTOM in Attributes Inspector.Because in button type RECT the default background color of button is BLUE.So when you click for changing the color of the button, it comes actual color(it changes to your required color) with BLUE color.So you need to set the button type as CUSTOM.
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return arrayButtonData.count;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
customCell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:#"cell"];
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"CustomCell" owner:self options:nil];
if (customCell==nil)
{
customCell = [nib objectAtIndex:0];
}
customCell.labelArrayListsNames.text = [NSString stringWithFormat:#"%#",[arrayButtonData objectAtIndex:indexPath.row]];
customCell.imageCircleRound.tag = indexPath.row;
NSLog(#"The custom cell button tag is - %ld",(long)customCell.imageCircleRound.tag);
NSLog(#"The label text is - %#",customCell.labelArrayListsNames.text);
[customCell.imageCircleRound addTarget:self action:#selector(cellCustomButtonClicked:)
forControlEvents:UIControlEventTouchUpInside];;
return customCell;
}
-(void)cellCustomButtonClicked:(UIButton *)sender
{
if(![sender isSelected])
{
[sender setBackgroundColor:[UIColor redColor]];
sender.Selected = YES;
}
else
{
[sender setBackgroundColor:[UIColor whiteColor]];
sender.Selected = NO;
}
}
It works fine.Check it.
enter code hereFor such problem use array of dictionary for tableview datasource array. Like this
NSMutableDictionary *datadict = [[NSMutableDictionary alloc] init];
[datadict setObject:#"Your title" forKey:#"Title"];
[datadict setObject:#"N" forKey:#"isSelected"];
[mainArray addObject: datadict]
put this code in loop for all your titles and N for isSelected key first time.
then you tableview method specially cellForRowAtIndexPath
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *Cell = [MaintableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
if (Cell == nil)
{
Cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
Cell.textLabel.text = [[mainArray objectAtIndex:indexPath.row] objectForKey:#"Title"];
UIButton *button=[UIButton buttonWithType:UIButtonTypeRoundedRect];
button.tag=indexPath.row;
[button addTarget:self
action:#selector(aMethod:) forControlEvents:UIControlEventTouchUpInside];
[button setTitle:#"" forState:UIControlStateNormal];
button.frame = CGRectMake(Cell.frame.size.width - 50, 10, 30, 30);
button.layer.cornerRadius = 60/2.0f;
button.layer.borderColor=[UIColor blackColor].CGColor;
if([[[mainArray objectAtIndex:indexPath.row] objectForKey:#"isSelected"] isEqualToString:#"Y"])
{
button.backgroundColor = [UIColor redColor];
}
else
{
button.backgroundColor = [UIColor whiteColor];
}
button.layer.borderWidth=2.0f;
//setting tag to button
button.tag=indexPath.row;
[Cell.contentView addSubview:button];
return Cell;
}
Then in your button action should be like
-(IBAction)aMethod :(id)sender
{
UIButton *selectedBtn = (UIButton *)sender;
if([[[mainArray objectAtIndex:[sender tag]] objectForKey:#"isSelected"] isEqualToString:#"Y"])
{
selectedBtn.backgroundColor = [UIColor whiteColor];
[[mainArray objectAtIndex:[sender tag]] removeObjectForKey:#"isSelected"];
[[mainArray objectAtIndex:[sender tag]] setObject:#"N" forKey:#"isSelected"];
}
else
{
selectedBtn.backgroundColor = [UIColor redColor];
[[mainArray objectAtIndex:[sender tag]] removeObjectForKey:#"isSelected"];
[[mainArray objectAtIndex:[sender tag]] setObject:#"Y" forKey:#"isSelected"];
}
}
you can also reload table in button action to see effect. It is good code technique to maintain multiple row selection and where data is large and realtime. By this we can get all selected rows whenever we needed on any event.

Button On Cell Not Performing Action

I have a button on TableView Cell. My Issue is that on clicking on cell and button we want to perform same action. on clicking a cell i m using did select method. Is their any method on clicking a button on cell they perform same action as cell did select perform.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *simpleTableIdentifier = [NSString stringWithFormat:#"%ld CustumCell",(long)indexPath.row];
CustumCell *cell = (CustumCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"CustumCell" owner:self options:nil];
cell = [nib objectAtIndex:2];
UIButton *button;
UIImageView *imageView;
UILabel *nameLabel;
if (screenWidth ==320) {
imageView =[[UIImageView alloc]initWithFrame:CGRectMake(0, 0, cell.contentView.frame.size.width-40, cell.contentView.frame.size.height+47)];
button=[[UIButton alloc]initWithFrame:CGRectMake(cell.contentView.frame.size.width-40, 0, 40, cell.contentView.frame.size.height+47)];
nameLabel=[[UILabel alloc]initWithFrame:CGRectMake(cell.contentView.frame.size.width/2-40, (cell.contentView.frame.size.height+20)/2, 100, 30)];
}
cell.selectionStyle=UITableViewCellSelectionStyleNone;
UIImageView *images = (UIImageView *)[cell.contentView viewWithTag:100];
images.image=[UIImage imageNamed:[tableImageArray objectAtIndex:indexPath.row]];
UIButton *buttond = (UIButton *)[cell.contentView viewWithTag:101];
[buttond setImage:[UIImage imageNamed:#"plus.png"] forState:UIControlStateNormal];
UILabel *label=(UILabel *)[cell.contentView viewWithTag:102];
label.text=[cellNameArray objectAtIndex:indexPath.row];
label.textColor =[UIColor whiteColor];
}
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
table.separatorStyle = UITableViewCellSeparatorStyleNone;
table.separatorStyle = UITableViewCellSeparatorStyleSingleLine;
SelectVoucher *selectVoucher=[[SelectVoucher alloc]initWithNibName:#"SelectVoucher" bundle:nil];
selectVoucher.hotelName =[cellNameArray objectAtIndex:indexPath.row];
[self presentViewController:selectVoucher animated:YES completion:nil];
}
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"CustumCell" owner:self options:nil];
cell = [nib objectAtIndex:2];
UIButton *button;
UIImageView *imageView;
UILabel *nameLabel;
if (screenWidth ==320) {
imageView =[[UIImageView alloc]initWithFrame:CGRectMake(0, 0, cell.contentView.frame.size.width-40, cell.contentView.frame.size.height+47)];
button=[[UIButton alloc]initWithFrame:CGRectMake(cell.contentView.frame.size.width-40, 0, 40, cell.contentView.frame.size.height+47)];
nameLabel=[[UILabel alloc]initWithFrame:CGRectMake(cell.contentView.frame.size.width/2-40, (cell.contentView.frame.size.height+20)/2, 100, 30)];
}
cell.selectionStyle=UITableViewCellSelectionStyleNone;
UIImageView *images = (UIImageView *)[cell.contentView viewWithTag:100];
images.image=[UIImage imageNamed:[tableImageArray objectAtIndex:indexPath.row]];
UIButton *buttond = (UIButton *)[cell.contentView viewWithTag:101];
[buttond setImage:[UIImage imageNamed:#"plus.png"] forState:UIControlStateNormal];
//This line you need to add
[buttond addTarget:self action:#selector(YourMethodtocall:) forControlEvents:UIControlEventTouchDown];**
/////
UILabel *label=(UILabel *)[cell.contentView viewWithTag:102];
label.text=[cellNameArray objectAtIndex:indexPath.row];
label.textColor =[UIColor whiteColor];
}
And out side of cellForRowAtIndexPath, you can write this method like
-(IBAction)YourMethodtocall:(id)sender {
//your code here to perform action
}
May helps you,
Enjoy Coding !!
If you want to get the action of the UIButton that just copy past your code and it's working.But if you want to disable the UIButton so just button.userInteractionEnabled=NO and then access the didSelected Method.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *simpleTableIdentifier = [NSString stringWithFormat:#"%ld CustumCell",(long)indexPath.row];
CustumCell *cell = (CustumCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"CustumCell" owner:self options:nil];
cell = [nib objectAtIndex:2];
UIButton *button;
UIImageView *imageView;
UILabel *nameLabel;
if (screenWidth ==320) {
imageView =[[UIImageView alloc]initWithFrame:CGRectMake(0, 0, cell.contentView.frame.size.width-40, cell.contentView.frame.size.height+47)];
button=[[UIButton alloc]initWithFrame:CGRectMake(cell.contentView.frame.size.width-40, 0, 40, cell.contentView.frame.size.height+47)];
nameLabel=[[UILabel alloc]initWithFrame:CGRectMake(cell.contentView.frame.size.width/2-40, (cell.contentView.frame.size.height+20)/2, 100, 30)];
}
cell.selectionStyle=UITableViewCellSelectionStyleNone;
UIImageView *images = (UIImageView *)[cell.contentView viewWithTag:100];
images.image=[UIImage imageNamed:[tableImageArray objectAtIndex:indexPath.row]];
UIButton *buttond = (UIButton *)[cell.contentView viewWithTag:101];
[buttond setImage:[UIImage imageNamed:#"plus.png"] forState:UIControlStateNormal];
[buttond addTarget:self action:#selector(btnAction:) forControlEvents:UIControlEventTouchUpInside];
[buttond setTitle:[NSString stringWithFormat:#"%li %li",(long)indexPath.section,(long)indexPath.row] forState:UIControlStateDisabled];
UILabel *label=(UILabel *)[cell.contentView viewWithTag:102];
label.text=[cellNameArray objectAtIndex:indexPath.row];
label.textColor =[UIColor whiteColor];
}
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
table.separatorStyle = UITableViewCellSeparatorStyleNone;
table.separatorStyle = UITableViewCellSeparatorStyleSingleLine;
SelectVoucher *selectVoucher=[[SelectVoucher alloc]initWithNibName:#"SelectVoucher" bundle:nil];
selectVoucher.hotelName =[cellNameArray objectAtIndex:indexPath.row];
[self presentViewController:selectVoucher animated:YES completion:nil];
}
-(void)btnAction:(UIButton*)sender{
NSString *str=[sender titleForState:UIControlStateDisabled];
NSArray *ar=[str componentsSeparatedByString:#" "];
NSIndexPath *indexPath=[NSIndexPath indexPathForRow:[[ar objectAtIndex:1] intValue] inSection:[[ar objectAtIndex:0] intValue]];
btnSelectedSignOut= sender;
NSLog(#"Value from sign out action %#",indexPath);
//here is the indexpath value you can do any logic here.
}
The best thing is to disable the userInteractionEnabled of the button, which will direct all the touches to the UITableView's delegate method - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath and you will be able to perform the cell touch events.
Alternatively, if at all you need to have the event of the button than set its userInteractionEnabled to YES and do add following code-
Inside cell creation method - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
add
[buttond addTarget:self action:#selector(cellButtonTouched:) forControlEvents:UIControlEventTouchUpInside];
add implement the event as
- (void) cellButtonTouched:(id)sender
{
}
You can define separate method for UIButton in UITableViewCell. if you want to perform separate action on clicking UIButton the didSelectRowAtIndexPath. kindly look over the code how to define separate action for UIButton.
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: CellIdentifier];
NSInteger index = indexPath.row;
if (cell == nil) {
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"cell"owner:self options:nil];
cell = [nib objectAtIndex:0];
UIButton *button=[UIButton buttonWithType:UIButtonTypeRoundedRect];
button.tag=indexPath.row;
[button addTarget:self action:#selector(aMethod:) forControlEvents:UIControlEventTouchDown];
[button setTitle:#"cellButton" forState:UIControlStateNormal];
button.frame = CGRectMake(80.0, 0.0, 160.0, 40.0);
[cell.contentView addSubview:button];
}
return cell;
}
To define selected method.
-(void)aMethod:(UIButton*)sender
{
NSLog(#"I Clicked a button %d",sender.tag);
}

How to identify the row index and section number of a clicked button in a custom cell inside tableview

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *simpleTableIdentifier = #"CustomCell";
cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"CustomCell" owner: self options: nil ];
cell = [nib objectAtIndex:0];
}
//cell.lblName.text = [items objectAtIndex:indexPath.row];
NSMutableDictionary *dic = [items objectAtIndex:indexPath.row];
cell.imgface.image = [dic objectForKey:#"Image"];
cell.imgface.layer.cornerRadius = cell.imgface.frame.size.width / 2;
cell.imgface.layer.borderWidth = 3.0f;
cell.imgface.layer.borderColor = [UIColor whiteColor].CGColor;
cell.imgface.clipsToBounds = YES;
cell.lblName.text = [dic objectForKey:#"Name"];
[cell.btnPhone setTitle:[dic objectForKey:#"Phone"] forState:(UIControlStateNormal)];
cell.btnPhone.tag = indexPath.row;
cell.btnstar.tag = indexPath.row;
[cell.btnPhone addTarget:self action:#selector(dial:) forControlEvents:(UIControlEventTouchUpInside)];
[cell.btnstar addTarget:self action:#selector(toggleimage:) forControlEvents:UIControlEventTouchUpInside];
if (indexPath.section == 0)
{
star = [UIImage imageNamed:#"Star-Favorites.png"];
[cell.btnstar setBackgroundImage:star forState:UIControlStateNormal];
}
else
{
star = [UIImage imageNamed:#"keditbookmarks.png"];
[cell.btnstar setBackgroundImage:star forState:UIControlStateNormal];
}
return cell;
}
write below code in button IBAction and you will get indexpath.row and indexpath.section
CGPoint buttonPosition = [sender convertPoint:CGPointZero toView:self.tableView];
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:buttonPosition];
NSLog(#"selected tableview row is %d",indexPath.row);
You have some different ways to do that:
• When you configure the cell set the tag of the cell or the button as the row and retrieve that on the IBAction (I hate tags though)
• Define a delegate for the table cell and set it when you configure it. Then call the delegate method passing the cell and find the relative index (-indexPathForCell:)
• The same as before but pass the cell through a notification instead of delegates
first of all on, button IBAction call this method
- (IBAction)btnClick:(UIButton)sender
{
UITableViewCell *cellOfcontrol=[self cellWithSubview:sender];
NSIndexPath *indexPath = [self.tableview indexPathForCell:cellOfcontrol];
}
cellWithSubview function
- (UITableViewCell *)cellWithSubview:(UIView *)subview
{
while (subview && ![subview isKindOfClass:[UITableViewCell self]])
subview = subview.superview;
return (UITableViewCell *)subview;
}

UIButton color changes after scrolling in UITableView

I have a tableview and I am setting its cells in xib. I have a button in it and when I click it, it changes button color from red to green. When I scroll tableview and come back to green button, it returns to red again. Here is my code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"ProgramCell";
ProgramCell *cell = (ProgramCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"ProgramCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
[cell.btnHatirlat addTarget:self action:#selector(remind:)
forControlEvents:UIControlEventTouchUpInside];
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
[cell.contentView setUserInteractionEnabled: NO];
return cell;
}
- (void) remind:(UIButton *)sender {
UIButton *btnTemp = (UIButton *)sender;
int iTag = btnTemp.tag;
// I want to change image of sender
[btnTemp setBackgroundColor:[UIColor greenColor]];
}
EDIT: I have added my solution as an answer. I hope it will help.
I'd do this:
The Tableview doesn't know how to "remember" the button state when it reuses the cell.
I'd create a NSMutableArray which holds a BOOL (or any other) flag wether the button is "on" or "off". Init that Array with all "off" if you like and then change the value at the index corresponding with the indexPath.row accordingly on click to "on".
Read the value in cellForRowAtIndexPath and change the color accordingly.
If you got multiple sections, create an Array for each section and let it hold an Array for the respective number of cells.
If that tableView is backed up by a DB add a flag for the state (on/off), and save it. Out of my head I don't know wether this requires a reloadData for everything to work as expected.
You need store pressed button's cell index.
Try this->
- (void)remind:(UIButton *)sender {
UIButton *btnTemp = (UIButton *)sender;
self.iTag = btnTemp.tag;
/*For many buttons
[btnTemp setSelected:![btnTemp isSelected]];
self.buttonStates[btnTemp.tag] = #([btnTemp isSelected);
*/
// I want to change image of sender
[btnTemp setBackgroundColor:[UIColor greenColor]];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"ProgramCell";
ProgramCell *cell = (ProgramCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"ProgramCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
if (self.iTag == indexPath.row) {
[cell.btnHatirlat setBackgroundColor:[UIColor greenColor]];
}
/*For many buttons
[cell.btnHatirlat setSelected:[self.buttonStates[indexPath.row] boolValue]];
if ([cell.btnHatirlat isSelected]) {
[cell.btnHatirlat setBackgroundColor:[UIColor greenColor]];
}
*/
[cell.btnHatirlat addTarget:self action:#selector(remind:)
forControlEvents:UIControlEventTouchUpInside];
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
[cell.contentView setUserInteractionEnabled: NO];
return cell;
}
Good luck!
Here is my solution and I want to thank again to #Bernard Grabowski and #MobiDevCom. I have saved clicked button's section and row number and checked if it is clicked or not.
(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"ProgramCell";
ProgramCell *cell = (ProgramCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"ProgramCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
NSString* strTemp = [NSString stringWithFormat: #"%d/%d", indexPath.section, indexPath.row ];
//To check clicked button at current section and row is clicked
for (int i = 0; i < buttonClickedArray.count; i++)
{
if([[self.buttonClickedArray objectAtIndex:i] isEqualToString:strTemp])
[cell.btnHatirlat setBackgroundColor:[UIColor greenColor]];
}
NSString *str = [[etkinlikArray objectAtIndex:indexPath.section] objectAtIndex:indexPath.row];
[cell.btnHatirlat addTarget:self action:#selector(remind:)
forControlEvents:UIControlEventTouchUpInside ];
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
[cell.contentView setUserInteractionEnabled: NO];
}
return cell;
}
- (void) remind:(UIButton *)sender
{
//to get clicked button's indexpath
UITableViewCell *clickedCell = (UITableViewCell *)[[sender superview] superview];
NSIndexPath *clickedButtonPath = [self.tableProgram indexPathForCell:clickedCell];
self.currentIndexPathStr = [NSString stringWithFormat: #"%d/%d", clickedButtonPath.section, clickedButtonPath.row];
[self.buttonClickedArray addObject:currentIndexPathStr];
[btnTemp setBackgroundColor:[UIColor greenColor]];
}

Resources