TableView cell reuse causing the button title to change while scrolling - ios

I am having a list displaying a name and a button titled as "Follow". When I tap on the button title should change to "UnFollow". If I tap on the button again the title should again change to "Follow". This is working fine, but when I am scrolling the table the title of the other cells are also changing due to cell reuse.
The code is as follows:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *CellIdentifier = #"AuthorsListCell";
AuthorsListTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier
forIndexPath:indexPath];
dic_eachAuthor = [[_arr_authors objectAtIndex:indexPath.row] mutableCopy];
cell.lbl_authorName.text = [dic_eachAuthor objectForKey:#"name"];
cell.btn_followOrUnfollow.tag = indexPath.row;
if([dic_eachAuthor valueForKey:#"follow"]){
[cell.btn_followOrUnfollow setTitle:#"UnFollow" forState:UIControlStateNormal];
}
else{
[cell.btn_followOrUnfollow setTitle:#"Follow" forState:UIControlStateNormal];
}
// action button method declarations
[cell.btn_followOrUnfollow addTarget:self action:#selector(followOrUnfollow:) forControlEvents:UIControlEventTouchUpInside];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
return cell;
}
-(void)followOrUnfollow:(UIButton *)sender
{
if ([sender.titleLabel.text isEqualToString:#"Follow"]) {
[sender setTitle:#"UnFollow" forState:UIControlStateNormal];
[dic_eachAuthor setValue:#"1" forKey:#"follow"];
}
else if ([sender.titleLabel.text isEqualToString:#"UnFollow"]) {
[sender setTitle:#"Follow" forState:UIControlStateNormal];
[dic_eachAuthor setValue:nil forKey:#"follow"];
}
}
Please suggest something to prevent the cell reuse.

Add this condition in followOrUnfollow in cellForRowAtIndexPath also
if ([sender.titleLabel.text isEqualToString:#"Follow"]) {
[sender setTitle:#"UnFollow" forState:UIControlStateNormal];
}
else if ([sender.titleLabel.text isEqualToString:#"UnFollow"]) {
[sender setTitle:#"Follow" forState:UIControlStateNormal];
}

Store follow/unfollow state information within datasource.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *CellIdentifier = #"CellIdentifier";
ListTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier
forIndexPath:indexPath];
cell.lbl_authorName.text = [[_arr_authors objectAtIndex:indexPath.row] objectForKey:#"name"];
cell.btn_followOrUnfollow.tag = indexPath.row;
// action button method declarations
[cell.btn_followOrUnfollow addTarget:self action:#selector(followOrUnfollow:) forControlEvents:UIControlEventTouchUpInside];
NSString *btnTitle = [[_arr_authors objectAtIndex:indexPath.row] objectForKey:#"userFollowUnfollow"];
[sender setTitle:btnTitle forState:UIControlStateNormal];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
return cell;
}
-(void)followOrUnfollow:(UIButton *)sender
{
if ([sender.titleLabel.text isEqualToString:#"Follow"]) {
[sender setTitle:#"UnFollow" forState:UIControlStateNormal];
}
else if ([sender.titleLabel.text isEqualToString:#"UnFollow"]) {
[sender setTitle:#"Follow" forState:UIControlStateNormal];
}
[[_arr_authors objectAtIndex:sender.tag] setValue:sender.titleLabel.text forKey:#"userFollowUnfollow"];
}

When you originally populate the table row, you do it from an array here cell.lbl_authorName.text = [[_arr_authors objectAtIndex:indexPath.row] objectForKey:#"name"];. The problem is that you don't populate the follow or unfollow information from this array. So all you are doing is toggling a button and there is no saving of the state of that button. What you need to do is modify the array to have a place to save the follow/unfollow state. Then populate the state in the table cell from this array. Then when you call followOrUnfollow: you need to modify the state in the array.
When the cell gets reused it goes and checks with the original array to populate it, populate the follow from the array and you will be set.
Edited to add some code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *CellIdentifier = #"CellIdentifier";
ListTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
cell.lbl_authorName.text = [[_arr_authors objectAtIndex:indexPath.row] objectForKey:#"name"];
cell.btn_followOrUnfollow.tag = indexPath.row;
if([[_arr_authors objectAtIndex:indexPath.row] valueForKey:#"follow"]){
[cell.btn_followOrUnfollow setTitle:#"UnFollow" forState:UIControlStateNormal];
else{
[cell.btn_followOrUnfollow setTitle:#"Follow" forState:UIControlStateNormal];
}
// action button method declarations
[cell.btn_followOrUnfollow addTarget:self action:#selector(followOrUnfollow:) forControlEvents:UIControlEventTouchUpInside];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
return cell;
}
-(void)followOrUnfollow:(UIButton *)sender
{
if ([sender.titleLabel.text isEqualToString:#"Follow"]) {
[sender setTitle:#"UnFollow" forState:UIControlStateNormal];
[[_arr_authors objectAtIndex:sender.tag] setValue:1 forKey:#"follow"]
}
else if ([sender.titleLabel.text isEqualToString:#"UnFollow"]) {
[sender setTitle:#"Follow" forState:UIControlStateNormal];
[[_arr_authors objectAtIndex:sender.tag] setValue:0 forKey:#"follow"]
}
}
I am not at my normal machine, so the syntax is probably off, but you should get the idea. Also note you will have to add the follow property to _arr_authors

You are missing something here, try this :
-(void)followOrUnfollow:(UIButton *)sender
{
NSDictionary *dict = (NSDictionary *) _arr_authors[sender tag];
if ([[dict objectForKey:#"name"] isEqualToString:#"Follow"])
{
[sender setTitle:#"UnFollow" forState:UIControlStateNormal];
}
else if ([[dict objectForKey:#"name"] isEqualToString:#"UnFollow"])
{
[sender setTitle:#"Follow" forState:UIControlStateNormal];
}
}

You are cells are reused so please implement this method in AuthorsListTableViewCell:
-(void) prepareForReuse{
[super prepareForReuse];
[self.btn_followOrUnfollow setTitle:#"Follow" forState:UIControlStateNormal];
}
// if the cell is reusable (has a reuse identifier), this is called just before the cell is returned from the table view method dequeueReusableCellWithIdentifier:. If you override, you MUST call super.
And set the correct default value to the cell.
I also recommend to implement this way:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *CellIdentifier = #"AuthorsListCell";
AuthorsListTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier
forIndexPath:indexPath];
cell.lbl_authorName.text = [dic_eachAuthor objectForKey:#"name"];
cell.btn_followOrUnfollow.tag = indexPath.row;
[cell.btn_followOrUnfollow setTitle:#"Follow forState:UIControlStateNormal];
[cell.btn_followOrUnfollow setTitle:#"UnFollow" forState:UIControlStateSelected];
if([dic_eachAuthor valueForKey:#"follow"]){
cell.btn_followOrUnfollow.selected = YES;
} else{
cell.btn_followorUnfollow.selected = NO;
}
// action button method declarations
[cell.btn_followOrUnfollow addTarget:self action:#selector(followOrUnfollow:) forControlEvents:UIControlEventTouchUpInside];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
return cell;
}
-(void)followOrUnfollow:(UIButton *)sender
{
sender.selected = !sender.selected;
if ([sender.titleLabel.text isEqualToString:#"Follow"]) {
[dic_eachAuthor setValue:#"1" forKey:#"follow"];
}
else if ([sender.titleLabel.text isEqualToString:#"UnFollow"]) {
[dic_eachAuthor setValue:nil forKey:#"follow"];
}
}
In AuthorsListTableViewCell
-(void) prepareForReuse{
[super prepareForReuse];
self.btn_followOrUnfollow.selected = NO;
}

Related

How to save the clicked button indexpath in custom cell?

Here is my problem, i have a custom cell in that 1 label and 4 buttons like question and answers,when the user click on the button 1 remaining 3 button go like this,
When the user scroll the cell it is not saving the what the user selected button i mean to say user click on the what ever the button it is not saving.
Here is my code,
ViewDidLoad()
{
testArray = [[NSMutableArray alloc]init];
for (int i =0; i<[mainArray count]; i++)
{
[testArray addObject:#"Unchecked"];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellId = #"Cell";
ContestQATableViewCell *cell =(ContestQATableViewCell *)[tableViewQA dequeueReusableCellWithIdentifier:cellId];
if (cell==nil)
{
NSArray *myNib;
myNib =[[NSBundle mainBundle]loadNibNamed:#"ContestQATableViewCell" owner:self options:nil];
cell = (ContestQATableViewCell *)[myNib lastObject];
}
cell.textLabel.text = [mainArray objectAtIndex:indexPath.row];
if([[testArray objectAtIndex:indexPath.row] isEqualToString:#"Unchecked"])
[cell.answer1 setImage:[UIImage imageNamed:#"RadioUnChecked"] forState:UIControlStateNormal];
else
[cell.answer1 setImage:[UIImage imageNamed:#"RadioChecked"] forState:UIControlStateNormal];
cell.answer1.tag = indexPath.row;
[cell.answer1 addTarget:self action:#selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
[cell.contentView addSubview:cell.answer1];
return cell;
[cell.answer1 addTarget:self action:#selector(buttonsClicked:) forControlEvents:UIControlEventTouchUpInside];
[cell.answer2 addTarget:self action:#selector(buttonsClicked:) forControlEvents:UIControlEventTouchUpInside];
[cell.answer3 addTarget:self action:#selector(buttonsClicked:) forControlEvents:UIControlEventTouchUpInside];
[cell.answer4 addTarget:self action:#selector(buttonsClicked:) forControlEvents:UIControlEventTouchUpInside];
return cell;
}
and here is my add target method
-(void)buttonsClicked:(id)sender
{
UIButton *btn=(UIButton *)sender;
ContestQATableViewCell * cell=(ContestQATableViewCell *) [btn.superview superview];
if (cell.answer1.tag==btn.tag)
{
[cell.answer1 setImage:[UIImage imageNamed:#"RadioChecked"] forState:UIControlStateNormal];
}else{
[cell.answer1 setImage:[UIImage imageNamed:#"RadioUnChecked"] forState:UIControlStateNormal];
}
if (cell.answer2.tag==btn.tag)
{
[cell.answer2 setImage:[UIImage imageNamed:#"RadioChecked"] forState:UIControlStateNormal];
}else{
[cell.answer2 setImage:[UIImage imageNamed:#"RadioUnChecked"] forState:UIControlStateNormal];
}
if (cell.answer3.tag==btn.tag)
{
[cell.answer3 setImage:[UIImage imageNamed:#"RadioChecked"] forState:UIControlStateNormal];
}else{
[cell.answer3 setImage:[UIImage imageNamed:#"RadioUnChecked"] forState:UIControlStateNormal];
}
if (cell.answer4.tag==btn.tag)
{
[cell.answer4 setImage:[UIImage imageNamed:#"RadioChecked"] forState:UIControlStateNormal];
}else{
[cell.answer4 setImage:[UIImage imageNamed:#"RadioUnChecked"] forState:UIControlStateNormal];
}
}
For Check-Uncheck functionality only buttonClicked: method is not enough. You will have also put the condition in cellForRowAtIndexPath: method for which button is selected or which in unselected because cellForRowAtIndexPath: method will call each time when you will scroll your UITableView and cells will be refresh.
for example
I explain in step by step
Step-1
Create the two arrays one for gloabally another one for checking purpose
#interface ViewController : UIViewController<UITableViewDelegate, UITableViewDataSource>
{
NSMutableArray *arrayforCheckUnchek; // handle which button is selected or which is unselected
NSMutableArray *originalArray; // original Array
}
Step-2
allocating the memory for arrays
- (void)viewDidLoad
{
[super viewDidLoad];
arrayforCheckUnchek = [[NSMutableArray alloc]init];
originalArray = [[NSMutableArray alloc]initWithObjects:#"cell1",#"cell2",#"cell3",#"cell4",#"cell5", nil];
// setting all cell initilayy at un check
for(int i=0; i<[originalArray count]; i++)
{
[arrayforCheckUnchek addObject:#"Unchecked"];
}
}
Step-2
setup your datasource Methods
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return [originalArray count];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *Identifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:Identifier];
if(cell == nil)
{
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
cell.textLabel.text = [originalArray objectAtIndex:indexPath.row];
UIButton *radiobutton = [UIButton buttonWithType:UIButtonTypeCustom];
[radiobutton setFrame:CGRectMake(270.0, 7.0, 30.0, 30.0)]; // customize the frames
if([[arrayforCheckUnchek objectAtIndex:indexPath.row] isEqualToString:#"Unchecked"])
[radiobutton setImage:[UIImage imageNamed:#"RadioUnChecked"] forState:UIControlStateNormal];
else
[radiobutton setImage:[UIImage imageNamed:#"RadioChecked"] forState:UIControlStateNormal];
radiobutton.tag = indexPath.row;
[radiobutton addTarget:self action:#selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
[cell.contentView addSubview:radiobutton];
return cell;
}
Step-3
here selected button index you can change the image
-(void)buttonClicked:(UIButton *)sender
{
//Getting the indexPath of cell of clicked button
CGPoint touchPoint = [sender convertPoint:CGPointZero toView:yourtableviewname];
NSIndexPath *indexPath = [yourtableviewname indexPathForRowAtPoint:touchPoint];
//Checking the condition button is checked or unchecked.
if([[arrayforCheckUnchek objectAtIndex:indexPath.row] isEqualToString:#"Unchecked"])
{
[sender setImage:[UIImage imageNamed:#"RadioChecked"] forState:UIControlStateNormal];
[arrayforCheckUnchek replaceObjectAtIndex:indexPath.row withObject:#"Checked"];
}
else
{
[sender setImage:[UIImage imageNamed:#"RadioUnChecked"] forState:UIControlStateNormal];
[arrayforCheckUnchek replaceObjectAtIndex:indexPath.row withObject:#"Unchecked"];
}
}

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 select radio button at a time in table view

I am having a radio button in table view cell. This is my radio button
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"myCell"];
if(cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"myCell"];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
UIButton *newRadioButton = [UIButton buttonWithType:UIButtonTypeCustom];
newRadioButton.frame = CGRectMake(30, 0, 15, 14.5);
[newRadioButton setImage:[UIImage imageNamed:#"unselect"] forState:UIControlStateNormal];
[newRadioButton setImage:[UIImage imageNamed:#"select"] forState:UIControlStateSelected];
cell.accessoryView = newRadioButton;
if ([indexPath isEqual:selectedIndex])
{
newRadioButton.selected = YES;
}
else
{
newRadioButton.selected = NO;
}
}
cell.textLabel.text = [array objectAtIndex:indexPath.row];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
selectedIndex = indexPath;
[table reloadData];
}
-(void)radiobtn:(id)sender
{
if([sender isSelected])
{
[sender setSelected:NO];
} else
{
[sender setSelected:YES];
}
}
Its working,But i want to select only one radio button at a time like this image (left). But for me selecting all the radio button (right).
I need to make it look like the first image.
I think you should try:
in YourViewController.h
#interface YourViewController : UITableViewController {
NSIndexPath *selectedIndex
}
in YourViewController.m
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"myCell"];
if(cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"myCell"];
UIButton *newRadioButton;
newRadioButton = [UIButton buttonWithType:UIButtonTypeCustom];
newRadioButton.frame = CGRectMake(30, 0, 15, 14.5);
[newRadioButton setImage:[UIImage imageNamed:#"unselect"] forState:UIControlStateNormal];
[newRadioButton setImage:[UIImage imageNamed:#"select"] forState:UIControlStateSelected];
cell.accessoryView = newRadioButton;
}
if ([indexPath isEqual:selectedIndex]) {
newRadioButton.seleted = YES;
} else {
newRadioButton.seleted = NO;
}
cell.textLabel.text = [array objectAtIndex:indexPath.row];
return cell;
}
and
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
selectedIndex = indexPath;
[tableView reloadData];
}
this link may help you
Unselect all the radio buttons before your if statement using something like this:
for (UITableViewCell *cell in [self visibleCells]) {
[[cell accessoryView] setSelected:NO];
}
When you are creating the button in cellForRowAtindexpth, attach an unique feature by which you can identify which button is being tapped. To do this UIButton has tag property
you need to set the tag for everybutton inside cellForRowAtindexpth, something like
// where i is just a static int variable for holding the count
myRadioButton.tag = i ;
i=i+1
now you when you tap based on tag, you can check which button is pressed and you can select that one
to know which button is pressed u can know like this
-(IBAction)buttonPressed:(id)sender{
UIButton *button = (UIButton *)sender;
NSLog(#"%d", [button tag]);
}
Try to reuse button
Solution: we can add & access controls by tag from view
if control found by tag we can use it.
if control not found we have to add it with tag.
UIButton *newRadioButton = (UIButton *)cell.accessoryView;
if (!newRadioButton || ![newRadioButton isKindOfClass:[UIButton class]]) {
UIButton *newRadioButton = [UIButton buttonWithType:UIButtonTypeCustom];
newRadioButton.frame = CGRectMake(30, 0, 15, 14.5);
[newRadioButton setImage:[UIImage imageNamed:#"unselect"] forState:UIControlStateNormal];
[newRadioButton setImage:[UIImage imageNamed:#"select"] forState:UIControlStateSelected];
cell.accessoryView = newRadioButton;
}

didSelectRowAtIndexPath is not invoked to UIButton of cellForRowAtIndex

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;
}

Add permanent checkmark to tableView-cell

my viewController contains a tableView where the user can add cells via coreData.
I defined the cells:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Travel";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
NSManagedObject *travel = [self.travelling objectAtIndex:indexPath.row];
UILabel *countryLabel = (UILabel *)[cell viewWithTag:101];
kategorieLabel.text = [travel valueForKey:#"country"];
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button setBackgroundImage:[UIImage imageNamed:#"button.png"] forState:UIControlStateNormal];
[button addTarget:self action:#selector(buttonTapped:) forControlEvents:UIControlEventTouchUpInside];
button.frame = CGRectMake(15.0f, 32.0f, 24.0f, 20.0f);
[cell addSubview:button];
if ([[travel valueForKey:#"tick"] isEqualToString:#"yes"]) {
[cell setAccessoryType:UITableViewCellAccessoryCheckmark];
}else{
[cell setAccessoryType:UITableViewCellAccessoryNone];
}
return cell;
}
- (void)buttonTapped:(UIButton *)sender {
UITableViewCell *owningCell = (UITableViewCell*)[sender superview];
[owningCell setAccessoryType:UITableViewCellAccessoryCheckmark];
NSIndexPath *indexPath = [_tableView indexPathForCell:owningCell];
NSManagedObject *travel = [self.travelling objectAtIndex:indexPath.row];
[travel setValue:#"yes" forKey:#"tick"];
}
When the user taps a button on the cell, the checkmark should appear. But when I reload or restart the app not all checkmarks are there. Maybe there is a better method to do this.

Resources