I am making an app in which i am using in the form of checkboxes. i want to show count of checkboxes in text label i am trying but could not find possible solution.. here is my project link https://www.dropbox.com/s/iu8fdz4y0ps4xye/checkboxwithTableview%202.zip?dl=0 kindly review it..
Below is my sample code
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *tableviewidentifier = #"cell";
TablecellTableViewCell *cell= [self.tblvie dequeueReusableCellWithIdentifier:tableviewidentifier];
if(cell==nil)
{
cell = [[TablecellTableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:tableviewidentifier];
}
cell.lblImage.layer.cornerRadius=3.0f;
cell.lblImage.layer.borderWidth=1.0f;
if ([self.checkimageArray containsObject:[self.lblArray objectAtIndex:indexPath.row]])
{
[cell.buttonCheckbox setImage:[UIImage imageNamed:#"checkBox.png"] forState:UIControlStateNormal];
// [cell.buttonCheckbox setImage:[UIImage imageNamed:#"checkBoxMarked.png"] forState:UIControlStateNormal];
}
else
{
//[cell.buttonCheckbox setImage:[UIImage imageNamed:#"checkBox.png"] forState:UIControlStateNormal];
[cell.buttonCheckbox setImage:[UIImage imageNamed:#"checkBoxMarked.png"] forState:UIControlStateNormal];
}
cell.buttonCheckbox.tag=indexPath.row;
[cell.buttonCheckbox addTarget:self action:#selector(checkButton:) forControlEvents:UIControlEventTouchUpInside];
cell.lblText.text=[self.lblArray objectAtIndex:indexPath.row];
return cell;
}
-(IBAction)checkButton:(UIButton *)sender
{
CGPoint buttonPosition = [sender convertPoint:CGPointZero toView:self.tblvie];
NSIndexPath *indexPath = [self.tblvie indexPathForRowAtPoint:buttonPosition];
if ([self.checkimageArray containsObject:[self.lblArray objectAtIndex:indexPath.row]]) {
[self.checkimageArray removeObject:[self.lblArray objectAtIndex:indexPath.row]];
self.titleLabel.text=#"";
}
else {
[self.checkimageArray addObject:[self.lblArray objectAtIndex:indexPath.row]];
NSArray *arr=[self.tblvie indexPathsForSelectedRows];// here i am declaring an array but array is coming nil
self.titleLabel.text=[self.lblArray objectAtIndex:indexPath.row];
}
[self.tblvie reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation: UITableViewRowAnimationFade];
}
Add Int variable in .h int checkBoxesCount;
Initialize it in ViewDidLoad like checkBoxesCount = 0;
Than Update your method like below
-(IBAction)checkButton:(UIButton *)sender
{
CGPoint buttonPosition = [sender convertPoint:CGPointZero toView:self.tblvie];
NSIndexPath *indexPath = [self.tblvie indexPathForRowAtPoint:buttonPosition];
if ([self.checkimageArray containsObject:[self.lblArray objectAtIndex:indexPath.row]]) {
[self.checkimageArray removeObject:[self.lblArray objectAtIndex:indexPath.row]];
checkBoxesCount = checkBoxesCount - 1;
self.titleLabel.text=[NSString stringWithFormat:#"Count %d",checkBoxesCount];
}
else {
[self.checkimageArray addObject:[self.lblArray objectAtIndex:indexPath.row]];
// self.titleLabel.text=[self.lblArray objectAtIndex:sender.tag];
checkBoxesCount = checkBoxesCount + 1;
self.titleLabel.text=[NSString stringWithFormat:#"Count %d",checkBoxesCount];
}
[self.tblvie reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation: UITableViewRowAnimationFade];
}
Problem resolved. I tested same on my end.
Related
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"];
}
}
I am using simple tableview and i have add button in every cell , The Problem is how to get button text from cell number second and any other cell number get button text i am using this code but its not working
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:1 inSection:0];
UITableViewCell *cell = [tbl_view cellForRowAtIndexPath:indexPath];
for( UITableViewCell *getview in cell.subviews)
{
if([getview isKindOfClass:[UIButton class]])
{
NSLog(#"sdfsdfsd");
// UIButton *button = (UIButton *);
}
}
This code is set button in tableview cell
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"SimpleTableItem";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
UILabel *fromLabel = [[UILabel alloc]initWithFrame:CGRectMake(60, 5, 250,20)];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
cell=[[UITableViewCell alloc] init];
}
cell.backgroundColor=[UIColor clearColor];
UIButton *button_chaeckbox = [UIButton buttonWithType:UIButtonTypeCustom];
button_chaeckbox.backgroundColor=[UIColor clearColor];
button_chaeckbox.frame = CGRectMake(10, 10, 15, 15);
if( [checkedArray containsObject:[NSString stringWithFormat:#"%ld",(long)indexPath.row]])
{
[button_chaeckbox setBackgroundImage:[UIImage imageNamed:#"checked_checkbox.png"] forState:UIControlStateNormal];
}else
{
[button_chaeckbox setBackgroundImage:[UIImage imageNamed:#"empty_box_b.png"] forState:UIControlStateNormal];
}
[button_chaeckbox setTitle:#"creaButtonname" forState:UIControlStateNormal];
button_chaeckbox.tag=indexPath.row;
[button_chaeckbox addTarget:self
action:#selector(checkboxAction:)
forControlEvents:UIControlEventTouchUpInside];
[cell addSubview:button_chaeckbox];
}
Please give me solution , i have try this code in ios 7 and ios 8 this is not working
Regards,
Nishant Chandwani
Do one thing give tag value for each button like
button_chaeckbox.tag=indexpath.row
in cellForRowAtIndexPath Method .
in checkboxAction do like this
NSString * titleText=sender.titleLabel.text
and you will check in button action method from which cell it is
like using conditions if(sender.tag == //your cell number second value//)
I think you want like this only .
Use this code for reuse cells in table view
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"SimpleTableItem";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
cell=[[UITableViewCell alloc] init];
UILabel *fromLabel = [[UILabel alloc]initWithFrame:CGRectMake(60, 5, 250,20)];
cell.backgroundColor=[UIColor clearColor];
UIButton *button_chaeckbox = [UIButton buttonWithType:UIButtonTypeCustom];
button_chaeckbox.backgroundColor=[UIColor clearColor];
button_chaeckbox.frame = CGRectMake(10, 10, 15, 15);
[button_chaeckbox addTarget:self
action:#selector(checkboxAction:)
forControlEvents:UIControlEventTouchUpInside];
[cell addSubview:button_chaeckbox];
button_chaeckbox.tag=1001;
}
if( [checkedArray containsObject:[NSString stringWithFormat:#"%ld",(long)indexPath.row]])
{
[button_chaeckbox setBackgroundImage:[UIImage imageNamed:#"checked_checkbox.png"] forState:UIControlStateNormal];
}else
{
[button_chaeckbox setBackgroundImage:[UIImage imageNamed:#"empty_box_b.png"] forState:UIControlStateNormal];
}
}
Use this code for get button from cell
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:1 inSection:0];
UITableViewCell *cell = [tbl_view cellForRowAtIndexPath:indexPath];
UIButton *button_chaeckbox=(UIButton*)[cell viewWithtag:1001]
You can try this
In cellForRowAtIndexPath
[cell.button setTitle:#"RAM" forState:UIControlStateNormal];
cell.button.tag=indexPath.row;
[cell.button addTarget:self action:#selector(cellBtn:) forControlEvents:UIControlEventTouchUpInside];
Selector method
-(void)cellBtn :(UIButton *)sender
{
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:sender.tag inSection:0];
AlertCustomCell *cell = [tableview cellForRowAtIndexPath:indexPath];
NSString *user = cell.button.titleLabel.text;
NSLog(#"Text of button is :%#",user);
}
I hope it will work
let me point out one thing. if you want to traverse through all the subviews of the table cell you have to make for( UITableViewCell *getview in cell.subviews) to for( UIView *getview in cell.subviews)
The code would look like this
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:1 inSection:0];
UITableViewCell *cell = [tbl_view cellForRowAtIndexPath:indexPath];
for( UIView *getview in cell.subviews)
{
if([getview isKindOfClass:[UIButton class]])
{
UIButton *button = (UIButton *)getView;
NSLog #("%#",button.titleLabel.text)
}
}
I would recommend making a UITableViewCell subclass and making the button a a property on that subclass. Then in your code would look something like this.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"SimpleTableItem";
CustomTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
UILabel *fromLabel = [[UILabel alloc]initWithFrame:CGRectMake(60, 5, 250,20)];
if (cell == nil) {
cell = [[CustomTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
cell.backgroundColor=[UIColor clearColor];
UIButton *button_chaeckbox = [UIButton buttonWithType:UIButtonTypeCustom];
button_chaeckbox.backgroundColor=[UIColor clearColor];
button_chaeckbox.frame = CGRectMake(10, 10, 15, 15);
if( [checkedArray containsObject:[NSString stringWithFormat:#"%ld",(long)indexPath.row]])
{
[button_chaeckbox setBackgroundImage:[UIImage imageNamed:#"checked_checkbox.png"] forState:UIControlStateNormal];
} else {
[button_chaeckbox setBackgroundImage:[UIImage imageNamed:#"empty_box_b.png"] forState:UIControlStateNormal];
}
[button_chaeckbox addTarget:self
action:#selector(checkboxAction:)
forControlEvents:UIControlEventTouchUpInside];
[cell setCellButton:button_chaeckbox];
return cell;
}
And then to get the button:
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:1 inSection:0];
CustomTableCell *cell = (CustomTableCell *)[tbl_view cellForRowAtIndexPath:indexPath];
UIButton * yourButton = cell.CellButton
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;
}
I am making an app in which i am using buttons in the form of checkboxes in uitableview cell.i am changing images on that checkbox select and unselect state. now i want that when i click on another button then all the cells of table view will be select and image of all the checkboxes of cells will changed? how it can done below is my sample code
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return self.lblArray.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *tableviewidentifier = #"cell";
TablecellTableViewCell *cell= [self.tblvie dequeueReusableCellWithIdentifier:tableviewidentifier];
if(cell==nil)
{
cell = [[TablecellTableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:tableviewidentifier];
}
cell.lblImage.layer.cornerRadius=3.0f;
cell.lblImage.layer.borderWidth=1.0f;
cell.backgroundColor=[UIColor colorWithRed:(245/255.0) green:(245/255.0) blue:(245/255.0) alpha:1];
if ([self.checkimageArray containsObject:[self.lblArray objectAtIndex:indexPath.row]])
{
[cell.buttonCheckbox setImage:[UIImage imageNamed:#"check_box_ok.png"]
forState:UIControlStateNormal];
}
else
{
[cell.buttonCheckbox setImage:[UIImage imageNamed:#"uncheck.png"]
forState:UIControlStateNormal];
}
cell.buttonCheckbox.tag=indexPath.row;
[cell.buttonCheckbox addTarget:self action:#selector(checkButton:) forControlEvents:UIControlEventTouchUpInside];
cell.lblText.text=[self.lblArray objectAtIndex:indexPath.row];
return cell;
}
-(IBAction)checkButton:(UIButton *)sender
{
CGPoint buttonPosition = [sender convertPoint:CGPointZero toView:self.tblvie];
NSIndexPath *indexPath = [self.tblvie indexPathForRowAtPoint:buttonPosition];
if ([self.checkimageArray containsObject:[self.lblArray objectAtIndex:indexPath.row]]) {
[self.checkimageArray removeObject:[self.lblArray objectAtIndex:indexPath.row]];
self.titleLabel.text=#"";
}
else {
[self.checkimageArray addObject:[self.lblArray objectAtIndex:indexPath.row]];
self.titleLabel.text=[self.lblArray objectAtIndex:sender.tag];
}
[self.tblvie reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation: UITableViewRowAnimationFade];
}
and here is my button in which i click then all the cells of tableview will select and images of all the cells will changed but it is not working
- (IBAction)selectbtns:(id)sender {
static NSString *tableviewidentifier = #"cell";
TablecellTableViewCell *cell= [self.tblvie dequeueReusableCellWithIdentifier:tableviewidentifier];
[cell.buttonCheckbox setImage:[UIImage imageNamed:#"check_box_ok.png"]
forState:UIControlStateNormal];
}
NSMutableArray *totalcheckmarkArray; //add on NSMutablearray in globally
- (void)viewDidLoad {
totalcheckmarkArray =[[NSMutableArray alloc]init];
for (int i=0; i<[self.lblArray count]; i++) // Number of Rows count
{
[self.totalcheckmarkArray addObject:#"NO"];
}
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *tableviewidentifier = #"cell";
TablecellTableViewCell *cell= [self.tblvie dequeueReusableCellWithIdentifier:tableviewidentifier];
if(cell==nil)
{
cell = [[TablecellTableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:tableviewidentifier];
}
cell.lblImage.layer.cornerRadius=3.0f;
cell.lblImage.layer.borderWidth=1.0f;
if(![[self.totalcheckmarkArray objectAtIndex:indexPath.row] isEqualToString:#"NO"])
{
[cell.buttonCheckbox setImage:[UIImage imageNamed:#"check_box_ok.png"] forState:UIControlStateNormal];
}
else if ([self.checkimageArray containsObject:[self.lblArray objectAtIndex:indexPath.row]])
{
[cell.buttonCheckbox setImage:[UIImage imageNamed:#"check_box_ok.png"] forState:UIControlStateNormal];
}
else
{
[cell.buttonCheckbox setImage:[UIImage imageNamed:#"uncheck.png"] forState:UIControlStateNormal];
}
cell.buttonCheckbox.tag=indexPath.row;
[cell.buttonCheckbox addTarget:self action:#selector(checkButton:) forControlEvents:UIControlEventTouchUpInside];
cell.lblText.text=[self.lblArray objectAtIndex:indexPath.row];
return cell;
}
selectAll Checkbox
- (IBAction)selectbtns:(id)sender {
for (int i=0; i<[self.lblArray count]; i++)
{
[totalcheckmarkArray replaceObjectAtIndex:i withObject:#"YES"];
}
[self.tblvie reloadData];
}
DeselectAll Checkbox
-(IBAction)deselectall_btnclick:(id)sender
{
for (int i=0; i<[self.lblArray count]; i++)
{
[totalcheckmarkArray replaceObjectAtIndex:i withObject:#"NO"];
}
[self.tblvie reloadData];
}
I can think of two possible solutions. If the following line works in cellForRowAtIndexPath:
if ([self.checkimageArray containsObject:[self.lblArray objectAtIndex:indexPath.row]]) {
[cell.buttonCheckbox setImage:[UIImage imageNamed:#"check_box_ok.png"] forState:UIControlStateNormal];
}
Then just add all the images to self.checkimageAray and then reload the table through [self.tblvie reloadData].
If there is a reason you don't want to reload the table, you could do the following, which will loop through all the cells in the table and execute the changes to each cell:
for (int section = 0; section < [self.tblvie numberOfSections]; section++) {
for (int row = 0; row < [self.tblvie numberOfRowsInSection:section]; row++) {
NSIndexPath* cellPath = [NSIndexPath indexPathForRow:row inSection:section];
TablecellTableViewCell *cell= [self.tblvie cellForRowAtIndexPath:cellPath];
[cell.buttonCheckbox setImage:[UIImage imageNamed:#"check_box_ok.png"]
forState:UIControlStateNormal];
}
}
I tend to iterate over every cell when I wish to make a change with an animation. If say you want to animate the checking of the box, the simplest way would be to place the animation block in the iteration of the cells.
If you wish to then unselect a cell, you could do the following:
for (int section = 0; section < [self.tblvie numberOfSections]; section++) {
for (int row = 0; row < [self.tblvie numberOfRowsInSection:section]; row++) {
NSIndexPath* cellPath = [NSIndexPath indexPathForRow:row inSection:section];
TablecellTableViewCell *cell= [self.tblvie cellForRowAtIndexPath:cellPath];
[cell.buttonCheckbox setImage:[UIImage imageNamed:#"uncheck.png"]
forState:UIControlStateNormal];
}
}
Please note that this is not changing your checkimageArray. While the cells are being displayed as selected, all of the images are not in your checkimageArray, and of corse with my solution for unselecting the cell, the images will not be removed from the checkimageArray either.
I would suggest adding all the objects from self.lblArray to checkimageArray where you place the code to set the cells highlighted and remove all objects from checkimageArray when you deselect them all. An example of how to add all images to the array is show in the other answer bellow.
You can do .
- (IBAction)selectbtns:(id)sender
{
self.checkimageArray = [NSArray arrayWithArray:self.lblArray];
[self.tableView reloadData];
}
I have two sections in my tableview(iOS), where the first one is for the "favorites" rows. If you select the accessoryView it should add/remove the selected object in the "objects" array to/from "favs" array depending if the object already exist in the section.
The method I wrote almost works, but when I add a second row, or the same to remove it in favorites, the app crashes with this error:
Terminating app due to uncaught exception NSRangeException', reason: *** -[__NSArrayM objectAtIndex:]: index 1 beyond bounds [0 .. 0]
The problem is that the index of the object in the corresponding arrays is not the same so I can't really figure out how to make this work properly.
Here's some code:
-(void)addToFavs:(id)sender{
UITapGestureRecognizer *gesture = (UITapGestureRecognizer *) sender;
NSLog(#"Tag = %d", gesture.view.tag);
//if favorite section is empty
if ([self.favs isEqualToArray:[#[]mutableCopy]]) {
NSLog(#"adding favorite");
[self.favs addObject:[self.objects objectAtIndex:gesture.view.tag]];
[self.subtitlesFavs addObject:[self.subtitles objectAtIndex:gesture.view.tag]];
[self.iconsFavs addObject:[self.icons objectAtIndex:gesture.view.tag]];
}
//if selected row already exist in favorites array <--HERE IS THE PROBLEM (I THINK)
else if([[self.objects objectAtIndex:gesture.view.tag] isEqualToString:[self.favs objectAtIndex:gesture.view.tag]]){
NSLog(#"removing favorite");
[self.favs removeObjectAtIndex:gesture.view.tag];
[self.subtitlesFavs removeObjectAtIndex:gesture.view.tag];
[self.iconsFavs removeObjectAtIndex:gesture.view.tag];
}else{
NSLog(#"adding favorite");
[self.favs addObject:[self.objects objectAtIndex:gesture.view.tag]];
[self.subtitlesFavs addObject:[self.subtitles objectAtIndex:gesture.view.tag]];
[self.iconsFavs addObject:[self.icons objectAtIndex:gesture.view.tag]];
}
[self.tableView reloadData];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// left image
UIImageView *image=[[UIImageView alloc] initWithFrame:CGRectMake(7, 7, 30, 30)];
[image.layer setCornerRadius:image.frame.size.width/2];
[image setClipsToBounds:YES];
if(indexPath.section==0){
image.image=[UIImage imageNamed:[self.iconsFavs objectAtIndex:indexPath.row]];
}else{
image.image=[UIImage imageNamed:[self.icons objectAtIndex:indexPath.row]];
}
//fav image
UIImageView *fav = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"favorites.png"]];
[fav setFrame:CGRectMake(0, 0, 25, 25)];
[fav setClipsToBounds:YES];
if(!indexPath.section==0) {
fav.image=[UIImage imageNamed:#"unfavorites"];
}
//cell
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell){
cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
cell.textLabel.text=self.objects[indexPath.row];
cell.detailTextLabel.text =self.subtitles[indexPath.row];
[cell.contentView addSubview:image];
cell.accessoryView = fav;
//Favorites
cell.accessoryView.userInteractionEnabled = YES;
cell.accessoryView.tag = indexPath.row;
UITapGestureRecognizer *tapped = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(addToFavs:)];
tapped.numberOfTapsRequired = 1;
[cell.accessoryView addGestureRecognizer:tapped];
//favorites section contents
if (indexPath.section == 0)
{
cell.textLabel.text=self.favs[indexPath.row];
[cell.contentView addSubview:image];
cell.detailTextLabel.text =self.subtitlesFavs[indexPath.row];
}
}
return cell;
}
Update 1
I edited my code with "isEqualToString" in the if-condition but it still doesn't work to remove them...
Quite similar to what you have but try this anyways:
this be the -cellForRowAtIndexPath: method --
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle
reuseIdentifier:CellIdentifier];
}
cell.detailTextLabel.textColor = [UIColor lightGrayColor];
//following commented line not needed
//cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
// left image
UIImageView *image = [[UIImageView alloc] init];
[image setFrame:CGRectMake(7, 7, 30, 30)];
[image.layer setCornerRadius:image.frame.size.width/2];
[image setClipsToBounds:YES];
[image.layer setBorderColor:[UIColor lightGrayColor].CGColor];
[image.layer setBorderWidth:0.3f];
[cell.contentView addSubview:image];
//favorites image button
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button setFrame:CGRectMake(0, 0, 25, 25)];
[button setBackgroundColor:[UIColor clearColor]];
[button setImage:[UIImage imageNamed:#"unfavorites.png"] forState:UIControlStateNormal];
[button setImage:[UIImage imageNamed:#"favorites.png"] forState:UIControlStateSelected];
[button setTag:100]; //tag needed later
[button addTarget:self action:#selector(addToFavs:event:) forControlEvents:UIControlEventTouchUpInside];
[button setShowsTouchWhenHighlighted:YES];
[cell setAccessoryView:button];
switch(indexPath.section) {
case 0: { //is first section (favourite)
image.image = [UIImage imageNamed: self.iconsFavs[indexPath.row]];
cell.textLabel.text = self.favs[indexPath.row];
cell.detailTextLabel.text = self.subtitlesFavs[indexPath.row];
[button setSelected:YES];
}
break;
case 1: { //is second section (all clubs)
image.image = [UIImage imageNamed: self.icons[indexPath.row]];
cell.textLabel.text = self.objects[indexPath.row];
cell.detailTextLabel.text = self.subtitles[indexPath.row];
//change state of button (thereby change button image)
if([self.favs containsObject: self.objects[indexPath.row]]) {
[button setSelected:YES];
} else {
[button setSelected:NO];
}
}
break;
}
//separator -- do the following on viewDidLoad instead
//[self.tableView setSeparatorInset:UIEdgeInsetsMake(0, 45, 0, 0)];
return cell;
}
this be the -addToFavs:event: method --
//No need for `-accessoryButtonTappedForRowWithIndexPath:` method
//it can be done in your following `-addToFavs:event:` method alone:
-(void)addToFavs:(id)sender event:(id)event
{
NSSet *touches = [event allTouches];
UITouch *touch = [touches anyObject];
CGPoint currentTouchPosition = [touch locationInView:self.tableView];
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:currentTouchPosition];
switch(indexPath.section) {
case 0: { //is first section (favourite)
//remove from favourites
//get indexPath for appropraite row in second section
NSUInteger i_indexOfFavInMain = [self.objects indexOfObject:self.favs [indexPath.row]];
NSIndexPath *indexOfFavInMain = [NSIndexPath indexPathForItem:i_indexOfFavInMain inSection:1];
[self.favs removeObjectAtIndex:indexPath.row];
[self.subtitlesFavs removeObjectAtIndex:indexPath.row];
[self.iconsFavs removeObjectAtIndex:indexPath.row];
//handle second section button (for the appropriate row)
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexOfFavInMain];
UIButton *btnTemp = (UIButton *)[cell viewWithTag:100];
[btnTemp setSelected:NO];
//reload first section
[self.tableView reloadSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationAutomatic];
}
break;
case 1: { //is second section (all clubs)
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
UIButton *btnTemp = (UIButton *)[cell viewWithTag:100];
if([self.favs containsObject:self.objects[indexPath.row]]) {
//remove from favourites
[self.favs removeObject:self.objects[indexPath.row]];
[self.subtitlesFavs removeObject:self.subtitles[indexPath.row]];
[self.iconsFavs removeObject:self.icons[indexPath.row]];
[btnTemp setSelected:NO];
} else {
//add to favourites
[self.favs addObject: self.objects[indexPath.row]];
[self.subtitlesFavs addObject: self.subtitles[indexPath.row]];
[self.iconsFavs addObject: self.icons[indexPath.row]];
[btnTemp setSelected:YES];
}
[self.tableView reloadSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationAutomatic];
}
break;
}
}
Here's the solution. Moving everything to accessoryButoonTappedForRowWithIndexPath and having four different cases did the trick. Also make sure to not have strings that are the same in the arrays otherwise it will remove all of them and you will get an index error.
-(void)addToFavs:(id)sender event:(id)event {
NSSet *touches = [event allTouches];
UITouch *touch = [touches anyObject];
CGPoint currentTouchPosition = [touch locationInView:self.tableView];
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint: currentTouchPosition];
if(indexPath!=nil){
[self tableView: self.tableView accessoryButtonTappedForRowWithIndexPath: indexPath];
}
}
- (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath{
if ([self.favs count]==0) {
NSLog(#"adding first favorite %#",[self.objects objectAtIndex:indexPath.row]);
[self.favs addObject:[self.objects objectAtIndex:indexPath.row]];
[self.subtitlesFavs addObject:[self.subtitles objectAtIndex:indexPath.row]];
[self.iconsFavs addObject:[self.icons objectAtIndex:indexPath.row]];
}else if (indexPath.section==0){
NSLog(#"removing favorite %#",[self.favs objectAtIndex:indexPath.row]);
[self.favs removeObjectAtIndex:indexPath.row];
[self.subtitlesFavs removeObjectAtIndex:indexPath.row];
[self.iconsFavs removeObjectAtIndex:indexPath.row];
}else if(indexPath.section==1 && [self.favs containsObject:[self.objects objectAtIndex:indexPath.row]]){
NSLog(#"removing favorite %#",[self.objects objectAtIndex:indexPath.row]);
[self.favs removeObject:[self.objects objectAtIndex:indexPath.row]];
[self.subtitlesFavs removeObject:[self.subtitles objectAtIndex:indexPath.row]];
[self.iconsFavs removeObject:[self.icons objectAtIndex:indexPath.row]];
}else{
NSLog(#"adding favorite %#",[self.objects objectAtIndex:indexPath.row]);
[self.favs addObject:[self.objects objectAtIndex:indexPath.row]];
[self.subtitlesFavs addObject:[self.subtitles objectAtIndex:indexPath.row]];
[self.iconsFavs addObject:[self.icons objectAtIndex:indexPath.row]];
}
[tableView reloadSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationAutomatic];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//cell
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell){
// left image
UIImageView *image=[[UIImageView alloc] initWithFrame:CGRectMake(7, 7, 30, 30)];
[image.layer setCornerRadius:image.frame.size.width/2];
[image setClipsToBounds:YES];
[image.layer setBorderColor:[UIColor lightGrayColor].CGColor];
[image.layer setBorderWidth:0.3f];
cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
cell.detailTextLabel.textColor=[UIColor lightGrayColor];
cell.textLabel.text=self.objects[indexPath.row];
cell.detailTextLabel.text =self.subtitles[indexPath.row];
[cell.contentView addSubview:image];
if(indexPath.section==0){
image.image=[UIImage imageNamed:[self.iconsFavs objectAtIndex:indexPath.row]];
cell.textLabel.text=self.favs[indexPath.row];
cell.detailTextLabel.text =self.subtitlesFavs[indexPath.row];
}else{
image.image=[UIImage imageNamed:[self.icons objectAtIndex:indexPath.row]];
}
//separetor
[self.tableView setSeparatorInset:UIEdgeInsetsMake(0, 45, 0, 0)];
//favorites image button
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
CGRect frame = CGRectMake(0.0, 0.0, 25, 25);
button.frame = frame;
button.showsTouchWhenHighlighted = YES;
[button setImage:[UIImage imageNamed:#"unfavorites.png"] forState:UIControlStateNormal];
[button setImage:[UIImage imageNamed:#"favorites.png"] forState:UIControlStateSelected];
[button addTarget:self action:#selector(addToFavs:event:) forControlEvents:UIControlEventTouchUpInside];
button.backgroundColor = [UIColor clearColor];
cell.accessoryView = button;
}
return cell;
}