Reputation:
I am trying to create a custom cell with favorite button on it. Its working fine but I think reuse identifier is creating problem here. I have tried it in two ways and it is working fine in both.
Here is my first try: When I am selecting the button, it is changing to yellow button and vice -versa. But after scrolling up or down,it is changing to its normal state again. Why?
-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *CI=@"CELL";
UITableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:CI];
if(!cell) {
cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CI];
}
favbtn=[[UIButton alloc]initWithFrame:CGRectMake(160, 10, 30, 35)];
[cell.contentView addSubview:favbtn];
[favbtn setBackgroundImage:[UIImage imageNamed:@"starr.png"] forState:UIControlStateNormal];
[favbtn addTarget:self action:@selector(fav:) forControlEvents:UIControlEventTouchUpInside];
cell.textLabel.text=[favdata objectAtIndex:indexPath.row];
return cell;
}
-(void)fav:(id)sender
{
if ([sender isSelected]) {
[sender setImage:[UIImage imageNamed:@"starr.png"] forState:UIControlStateNormal];
[sender setSelected:NO];
} else {
[sender setImage:[UIImage imageNamed:@"star.png"] forState:UIControlStateSelected];
[sender setSelected:YES];
}
}
Here is my second try:
Here every sixth cell is showing the same state.
-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *CI=@"CELL";
UITableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:CI];
if(!cell) {
cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CI];
favbtn=[[UIButton alloc]initWithFrame:CGRectMake(160, 10, 30, 35)];
[cell.contentView addSubview:favbtn];
[favbtn setBackgroundImage:[UIImage imageNamed:@"starr.png"] forState:UIControlStateNormal];
[favbtn addTarget:self action:@selector(fav:) forControlEvents:UIControlEventTouchUpInside];
cell.textLabel.text=[favdata objectAtIndex:indexPath.row];
}
return cell;
}
Upvotes: 0
Views: 522
Reputation: 585
You need to understand the way the cell is being reused. When your cell is scrolled out of the screen, it will be reused for the cell that is entering the screen. Table view will keep calling the method cellForRowAtIndexPath
every time they want to render the cell. In your code, you init a new favbtn all the time, so even if the cell already contains it and being reused, you will keep on adding more buttons into it. Here's my suggestions:
UITableViewCell
. Let's say FavoriteCell
. Put all your code to add the favorite button inside your subclass.ViewDidLoad
register your cell with your table view. Something like this: [self.tableView registerClass:...]
or [self.tableView registerNib:...]
depending on if you have a nib file for your cell or not.cellForRowAtIndexPath
, dequeue your cell as usual but you don't have to check if it's nil or not, and you don't have to create the favorite button since you already put it inside your subclass.Just remember that, the method cellForRowAtIndexPath
will be called all the time so your logic of inserting favorite button has to be done properly. Make sure that you only insert it once and update its property properly.
Upvotes: 1
Reputation: 6342
First of all modify this methods:
-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *CI=@"CELL";
UIButton * favbtn;
UITableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:CI];
if(!cell)
{
cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CI];
favbtn=[[UIButton alloc]initWithFrame:CGRectMake(160, 10, 30, 35)];
[cell.contentView addSubview:favbtn];
[favbtn setTag:11221133];
}
favbtn = [cell.contentView viewWithTag:11221133];
[favbtn setBackgroundImage:[UIImage imageNamed:@"starr.png"] forState:UIControlStateNormal];
[favbtn setImage:[UIImage imageNamed:@"starr.png"] forState:UIControlStateNormal];
[favbtn setImage:[UIImage imageNamed:@"star.png"] forState: UIControlStateSelected];
//Check selections here and if this index is selected make btn selected.
[favbtn addTarget:self action:@selector(fav:) forControlEvents:UIControlEventTouchUpInside];
cell.textLabel.text=[favdata objectAtIndex:indexPath.row];
cell.contentView.tag = indexPath.row;
return cell;
}
-(void)fav:(id)sender
{
UIButton * btn = (UIButton *)sender;
btn.selected = !btn.selected;
int index = [[btn superview] tag]; // use this index for storing selections
}
Then make a array for storing selections. Compare this selection in cellForRowAtIndexPath
and make btn selected or not selected.
Hope this will help you.....
Upvotes: 0