iOS Custom Cell - Reuse identifier - ios

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

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.....

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:
Create your own subclass of UITableViewCell. Let's say FavoriteCell. Put all your code to add the favorite button inside your subclass.
In 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.
In 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.

Related

Maintain state of custom button in UITableview cell when scrolls

I know this question is very similar to other questions, but i doesn't resolve the problem using that approach.i follow most of the available solution but it doesn't work for me..
I know that when tableview scrolls it reuse cell but i doesn't know the approach of maintaining the button state . i'll try with following link
How to use Reusable Cells in uitableview for IOS
IOS: Maintaining button state in uitableviewcell
How to Handle Favourite button clicks in custom Tableview cells iOS?
I done all the things.use tags, use touch points and all but nothing seems to work for me.so help me out..and here is my sample code
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
cell = (subcategoryCell *)[tableView dequeueReusableCellWithIdentifier:NSStringFromClass([subcategoryCell class]) forIndexPath:indexPath];
/*
* Set button for cell to subscribe with it
*/
cell.btnsubscribe = (UIButton *)[cell.contentView viewWithTag:303];
cell.btnsubscribe.tag = indexPath.row ;
[cell.btnsubscribe addTarget:self action:#selector(clickBtnSubscribe:) forControlEvents:UIControlEventTouchUpInside];
if (![_arraybtnState containsObject:listid] )
{
[cell.btnsubscribe setImage:[UIImage imageNamed:#"follow"] forState:UIControlStateNormal];
[cell.btnsubscribe setSelected:YES];
}
else {
[cell.btnsubscribe setImage:[UIImage imageNamed:#"following"] forState:UIControlStateNormal];
[cell.btnsubscribe setSelected:NO];
}
return cell;
}
_arrbtnstate contains the ids that user follows.
and listid contains unique id comes from database too
And the click event method...
- (IBAction)clickBtnSubscribe:(id)sender {
UIButton *button = (UIButton*)sender;
NSLog(#"selected button tag %li", (long)button.tag);
NSNumber *tagnum = [NSNumber numberWithLong:(long)button.tag];
if (button.selected) {
[self.arraybtnState addObject:tagnum];
[button setImage:[UIImage imageNamed:#"following"] forState:UIControlStateNormal];
NSLog(#"Subscribe");
[self subscribeButton:button.tag];
[button setSelected:NO];
}
else
{
[self.arraybtnState removeObject:tagnum];
[button setImage:[UIImage imageNamed:#"follow"] forState:UIControlStateNormal];
NSLog(#"unsubscribe");
[self unsubscribeButton:button.tag];
[button setSelected:YES];
}
}
Note: In this code, button is created in storyboard.,but i'll also tried without storyboard too.
First of all this line cell.btnsubscribe = (UIButton *)[cell.contentView viewWithTag:303]; is to be changed. Follow the below steps and try
in custom subcategoryCell connect IBOutlet to btnsubscribe.
in storyboard, you can set both selected and not normal images to a UIButton, here it is btnsubscribe. If you find it difficult follow this
in cellForRowAtIndexPath: remove below lines
[cell.btnsubscribe setImage:[UIImage imageNamed:#"follow"] forState:UIControlStateNormal];
[cell.btnsubscribe setImage:[UIImage imageNamed:#"following"] forState:UIControlStateNormal];
cell.btnsubscribe = (UIButton *)[cell.contentView viewWithTag:303];
update the following lines
if (![_arraybtnState containsObject:listid] )
{
[cell.btnsubscribe setSelected:YES];
}
else {
[cell.btnsubscribe setSelected:NO];
}
or simply [cell.btnsubscribe setSelected:(![_arraybtnState containsObject:listid] )];
Keep the addTarget in cell for row method (since you have custom cell class, it is better to move the button action to cell class and pass the result to viewcontroller by callback or delegate. not discussing that now but recomments) and update the clickBtnSubscribe: by removing
[button setImage:[UIImage imageNamed:#"following"] forState:UIControlStateNormal];
[button setImage:[UIImage imageNamed:#"follow"] forState:UIControlStateNormal];
these lines. assumes other parts are working properly.
You are setting Selected and unselected image for button's Normal state in both cases i.e UIControlStateNormal.
When you are using selected method you do not require to setImage again. Just set Image for Normal and selected state for button properly in cellForRowAtIndexpath or in xib. You are done.
First remove the setting image in clickBtnSubscribe:() method.
Now in your storyboard set images for Normal and selected state.
Also remove set Image in cell for row at indexpath as you have already done in view.
You can maintain the state of the buttons as-
// initialize your array only once
_arraybtnState = [[NSMutableArray alloc] init];
// cell for row at index path would be
//initially each cell will have follow image
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
cell = (subcategoryCell *)[tableView dequeueReusableCellWithIdentifier:NSStringFromClass([subcategoryCell class]) forIndexPath:indexPath];
[cell.btnsubscribe setTag: indexPath.row];
[cell.btnsubscribe addTarget:self action:#selector(clickBtnSubscribe:) forControlEvents:UIControlEventTouchUpInside];
if (![_arraybtnState containsObject:[NSNumber numberWithInt:indexPath.row]] )
{
[cell.btnsubscribe setImage:[UIImage imageNamed:#"follow"] forState:UIControlStateNormal];
[cell.btnsubscribe setSelected:YES];
}
else
{
[cell.btnsubscribe setImage:[UIImage imageNamed:#"following"] forState:UIControlStateNormal];
[cell.btnsubscribe setSelected:NO];
}
return cell;
}
- (IBAction)clickBtnSubscribe:(id)sender {
UIButton *button = (UIButton*)sender;
NSLog(#"selected button tag %li", (long)button.tag);
NSNumber *tagnum = [NSNumber numberWithLong:(long)button.tag];
if (button.selected) {
[self.arraybtnState addObject:tagnum];
NSLog(#"Subscribe");
[self subscribeButton:button.tag];
[button setSelected:NO];
}
else
{
[self.arraybtnState removeObject:tagnum];
NSLog(#"unsubscribe");
[self unsubscribeButton:button.tag];
[button setSelected:YES];
}
//after doing modification update the respective row as
UIButton *button = (UIButton *)sender;
// Find Point in Superview
CGPoint pointInSuperview = [button.superview convertPoint:button.center toView:self.tableView];
// Infer Index Path
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:pointInSuperview];
//relaod the row
NSArray* indexPathModel = [NSArray arrayWithObjects:indexPath, nil];
[self.tableView reloadRowsAtIndexPaths: indexPathModel withRowAnimation:UITableViewRowAnimationNone];
}
reloading row will reflect the changes done in the modal to the UI.
I think you can put this line in viewDidLoad or after you load what all have subscribed .
_arraybtnState = [NSMutableArray arrayWithArray:[self.strSubscribe componentsSeparatedByString:#","]];
Then the cellForRowAtIndexPath will loook like below
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
cell = (subcategoryCell *)[tableView dequeueReusableCellWithIdentifier:NSStringFromClass([subcategoryCell class]) forIndexPath:indexPath];
/*
* Set button for cell to subscribe with it
*/
cell.btnsubscribe = (UIButton *)[cell.contentView viewWithTag:303];
cell.btnsubscribe.tag = indexPath.row ;
[cell.btnsubscribe addTarget:self action:#selector(clickBtnSubscribe:) forControlEvents:UIControlEventTouchUpInside];
if (![_arraybtnState containsObject:[NSNumber numberWithInt:indexPath.row]] ) {
[cell.btnsubscribe setImage:[UIImage imageNamed:#"follow"] forState:UIControlStateNormal];
}
else {
[cell.btnsubscribe setImage:[UIImage imageNamed:#"following"] forState:UIControlStateNormal];
}
return cell;
}
and then the btn click method as
- (IBAction)clickBtnSubscribe:(id)sender {
UIButton *button = (UIButton*)sender;
NSLog(#"selected button tag %li", (long)button.tag);
NSNumber *tagnum = [NSNumber numberWithLong:(long)button.tag];
if (![_arraybtnState containsObject:tagnum] )
{
[_arraybtnState addObject:tagnum];
[button setImage:[UIImage imageNamed:#"following"] forState:UIControlStateNormal];
NSLog(#"Subscribe");
[self subscribeButton:button.tag];
}
else {
[self.arraybtnState removeObject:tagnum];
[button setImage:[UIImage imageNamed:#"follow"] forState:UIControlStateNormal];
NSLog(#"unsubscribe");
[self unsubscribeButton:button.tag];
}
}
Two easy solutions and quite fast to implement :
Keep track of the state in an array/dictionary
You can store your states in an array of states, i'll make an example.
(Note: i'm coding this without compiling, I might mispel some stuff, feel free to edit my post)
in your viewDidLoad
arrState = [[NSMutableArray alloc]init];
for (yourObject *object in dataArray){
//For every object that you use to load your tableview, this can be strings or anything really
[arrState addObject:#NO];
}
In your cellForRow
...
//This will either put YES or NO depending on the element in the state array.
[cell.button setSelected:[arrState objectAtIndex:indexPath.row]];
...
Boom, done.
You can also keep track of this in a database or anything persistent, and then you'd simply load whatever your field contains for a selected record. This is more relevant if we're talking about, for example, something like favourites or something that will be there until the user decides otherwise. If it's just to keep track of your button states during the lifetime of your view, then ignore this part of the answer.
If you need to keep it alive forever (even when the app closes), then you'd most probably need a database :)

UITableview not updating uitableviewcell custom cell from storyboard

I have tried as many as solution I found to resolve this problem.
My latest code is show blow:
static NSString *simpleTableIdentifier = #"cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
[[cell viewWithTag:1000] removeFromSuperview];
[[cell viewWithTag:2000] removeFromSuperview];
// other code for setting view that works perfect then
if(some condition){
UIButton *btn=[UIButton buttonWithType:UIButtonTypeCustom];
[btn setImage:[UIImage imageNamed:#"upgrey.png"] forState:UIControlStateNormal];
btn.frame=upButton.frame;
[btn addTarget:self action:#selector(upButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
[cell addSubview:btn];
UIButton *btn2=[UIButton buttonWithType:UIButtonTypeCustom];
[btn2 setImage:[UIImage imageNamed:#"downgrey.png"] forState:UIControlStateNormal];
btn2.frame=downButton.frame;
[btn2 addTarget:self action:#selector(downButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
[cell addSubview:btn2];
btn.tag=1000;
btn2.tag=2000;
}
return cell;
but this does not work. if i add
[[cell viewWithTag:1000] removeFromSuperview];
[[cell viewWithTag:2000] removeFromSuperview];
in start it remove buttons from all cells. and if i do not use this. it shows all cells with these two buttons.
thanks in advance.
Even though you've already accepted your own answer, I'll take a moment to explain why you had that issue and how you can better structure your UITableViews in the future.
The reason why "it shows all cells with these two buttons" when you don't have those removeFromSubview lines is because by implementing dequeueReusableCellWithIdentifier:, you're reusing your cells and the contents thereof. Repeatedly adding the same subview during each call of cellForRowAtIndexPath makes the fact that you're reusing the cells completely pointless since you're reusing absolutely nothing within them. So either, don't reuse your cells at all or, better yet since each cell's contents are exactly the same, do reuse your cells and also reuse those buttons.
There are two good ways to do this. One way to do this is to create a UITableViewCell custom subclass. But since your cells' contents are fairly simple and you say your else conditional's already functional, I'll suggest a different way that might be a bit less code-intensive. Here's my suggestion:
- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// Create two identifiers -- one for "some condition" one
// for the "other condition"
static NSString *simpleTableIdentifier1 = #"cell1";
static NSString *simpleTableIdentifier2 = #"cell2";
if (some condition) {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier1];
// Only add the buttons when cell == nil, i.e. during the first
// time cell's initialized to hold a UITableViewCell
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier1]
UIButton *btn=[UIButton buttonWithType:UIButtonTypeCustom];
[btn setImage:[UIImage imageNamed:#"upgrey.png"] forState:UIControlStateNormal];
btn.frame=upButton.frame;
[btn addTarget:self action:#selector(upButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
[cell addSubview:btn];
UIButton *btn2=[UIButton buttonWithType:UIButtonTypeCustom];
[btn2 setImage:[UIImage imageNamed:#"downgrey.png"] forState:UIControlStateNormal];
btn2.frame=downButton.frame;
[btn2 addTarget:self action:#selector(downButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
[cell addSubview:btn2];
}
} else {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier2];
if (cell == nil) {
....

UIButton of UITableViewCell disappear on scroll

I Have a problem with my custom UItableViewCell. It's seems that all UIButton of UITableViewCell disappear on scroll. Specilay on my 25 cell. Any one have any idea ?
any help would be appreciated :)
That some code :
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString* cellIdentifier = #"Cell";
Cell * __strong cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (!cell){
cell = [[Cell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
InfoObject __weak *obj = [_pos objectAtIndex:indexPath.row];
[cell configCell];
cell.id = obj.id;
{// EVENT ON BUTTON
[cell.checkbox addTarget:self action:#selector(checkup:) forControlEvents:UIControlEventTouchUpInside];
[cell.btnPaymentState addTarget:self action:#selector(changePaymentState:) forControlEvents:UIControlEventTouchUpInside];
}
{// SET BUTTON CHECKBOX
cell.checkbox.tag = indexPath.row;
[cell.checkbox setImage:[UIImage imageNamed:IMG_BLACK_UNCHECKBOX] forState:UIControlStateNormal];
[cell.checkbox setImage:[UIImage imageNamed:IMG_BLACK_CHECKBOX] forState:UIControlStateSelected];
[cell.checkbox setImage:[UIImage imageNamed:IMG_BLACK_CHECKBOX] forState:UIControlStateHighlighted];
}
{// SET BUTTON PAYMENT STATE
cell.btnPaymentState.tag = indexPath.row;
[cell.btnPaymentState setImage:[self getImageAssociateWithName:obj.stringPaymentState] forState:UIControlStateNormal];
[cell.btnPaymentState setImage:[self getImageAssociateWithName:obj.stringPaymentState] forState:UIControlStateSelected];
[cell.btnPaymentState setImage:[self getImageAssociateWithName:obj.stringPaymentState] forState:UIControlStateHighlighted];
}
[self SetSelectedBackgroundColorSelectedForFolderCellAtRow:indexPath.row
:obj.selected Cell: cell];
[cell.checkbox setSelected:obj.selected];
[self setCellColorTextOfObjectPrepare:cell withObj:obj];
return cell;
}
I solve my problem. The problem is that i was using Tag for my UIButton and the identifier was the same number tag of another UIView so when i was removing my UIView the UIButton disappear also. Thanks all for your answer.
Remove if (!cell)
And you're good to go.

Two UITableViewCell have the same indexPath?

I have a problem like this:
I have a table view. when i click on a cell (or row), the cell will add 2 more buttons and re-size.
This function it work fine!
The problem is when i click first row,
it creates 2 buttons and re-size
and then scroll down, another cell also display 2 buttons.
and this is my code for function of displaying button and resizing cell
I believe when scrolling down the table is reloaded and reset the indexPath, so 2 cells both display the buttons.
Anyone has any suggestion!?
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
tvcCategory *cell = (tvcCategory*)[tableView cellForRowAtIndexPath:indexPath];
NSLog(#"- %i ", indexPath.item);
if (selectedIndex.item != indexPath.item) {
[btnEdit removeFromSuperview];
[btnTransact removeFromSuperview];
objSession.catId = cell.lblId.text;
btnEdit = [UIButton buttonWithType:UIButtonTypeRoundedRect];
btnEdit.frame = CGRectMake(91, 72, 73, 35);
[btnEdit setTitle:#"Edit" forState:UIControlStateNormal];
[btnEdit setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
[btnEdit setBackgroundImage:buttonImage forState:UIControlStateNormal];
[btnEdit setBackgroundImage:buttonImageHighlight forState:UIControlStateHighlighted];
[btnEdit addTarget:self action:#selector(moveToEditingScreen) forControlEvents:UIControlEventTouchUpInside];
btnTransact = [UIButton buttonWithType:UIButtonTypeRoundedRect];
btnTransact.frame = CGRectMake(176, 72, 95, 35);
[btnTransact setTitle:#"Transact" forState:UIControlStateNormal];
[btnTransact setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
[btnTransact setBackgroundImage:buttonImage forState:UIControlStateNormal];
[btnTransact setBackgroundImage:buttonImageHighlight forState:UIControlStateHighlighted];
[btnTransact addTarget:self action:#selector(moveToTransactionScreen) forControlEvents:UIControlEventTouchUpInside];
[tableView reloadData];
[cell.contentView addSubview:btnEdit];
[cell.contentView addSubview:btnTransact];
lastClickedCell = cell;
self.selectedIndex = indexPath;
NSIndexPath* rowToReload = [NSIndexPath indexPathForRow:-1 inSection:0];
NSArray* rowsToReload = [NSArray arrayWithObjects:rowToReload, nil];
[tableView reloadRowsAtIndexPaths:rowsToReload withRowAnimation:UITableViewRowAnimationFade];
[tableView cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryCheckmark;
}
else
{
[tableView reloadData];
[tableView cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryCheckmark;
}
}
I really appreciate
The problem that you are facing, like the guys has had exposed in the comments is that in the table view method you need to reuse cells to optimize the performance, so you need to take this cells that are already used and adjust it to your expected cell state.
Probably in your cellForRowAtIndexPath you are just taking care to allocate it and adjust it when you do not have a cell, you will need to adjust it, you have some options, like always adjust it to the initial state or you can check if the buttons are showed and only in this cases redesign your cell.
So in your class, at some point you have this method:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if(cell == nil){
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
} else {
if([selectedIndex isEqual:indexPath]){
//Add your buttons and adjust the cell to show the extra buttons
} else {
if(your selected index isn't in the screen anymore){
[btnEdit removeFromSuperview];
[btnTransact removeFromSuperview];
}
//your others adjusts
}
}
}
EDIT:
[[yourTable indexPathsForVisibleRows] containsObject:selectedIndexPath];
This method return an array that you need to check if your selectedindex is inside it.
More about UITableView you can found at the documentation.

SubView added to the contentView of UITableViewCell is removed after Scrolling?

In my application I load a tableView with an array and I've added an UIButton to each row as subView for my need. I know that the reused cell will have the added button So keeping this fact in mind I've Implemented the -cellForRowAtIndexPath method like below
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:#"surgeon"];
if (!cell) {
cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"surgeon"];
}
[[cell.contentView subviews]
makeObjectsPerformSelector:#selector(removeFromSuperview)];
//before adding button to the contentView I've removed allSubViews
UIButton *btn=[UIButton buttonWithType:UIButtonTypeCustom];
[btn setFrame:CGRectMake(142, 4, 28, 28)];
[btn setImage:[UIImage imageNamed:[NSString stringWithFormat:#"infoicon.png"]] forState:UIControlStateSelected];
[btn setSelected:YES];
[btn addTarget:self action:#selector(checkbtnClicked:) forControlEvents:UIControlEventTouchUpInside];
[btn setTag:indexPath.row];
if (indexPath.row==1) {
NSLog(#"CELL %# CONTNTVEW %#",cell.subviews,cell.contentView.subviews);
}
[cell.contentView addSubview:btn];
return cell;
}
My problem is that the TableView is loaded well at first time But when I scroll the TableView the Button I have added is Removed even though the removing of subView is done before adding the Button as subView help me to get This work
It appears that removing all of the subviews of the cell's content view is causing the cell to re-create its cell content when you set the text. I've managed to reproduce the problem, and fixed it by using this method instead:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:#"surgeon"];
if (!cell) {
cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"surgeon"];
}
for(UIView *subview in cell.contentView.subviews)
{
if([subview isKindOfClass: [UIButton class]])
{
[subview removeFromSuperview];
}
}
//before adding button to the contentView I've removed allSubViews
UIButton *btn=[UIButton buttonWithType:UIButtonTypeCustom];
[btn setFrame:CGRectMake(142, 4, 28, 28)];
[btn setImage:[UIImage imageNamed:[NSString stringWithFormat:#"infoicon.png"]] forState:UIControlStateSelected];
[btn setSelected:YES];
[btn addTarget:self action:#selector(checkbtnClicked:) forControlEvents:UIControlEventTouchUpInside];
[btn setTag:indexPath.row];
if (indexPath.row==1) {
NSLog(#"CELL %# CONTNTVEW %#",cell.subviews,cell.contentView.subviews);
}
cell.textLabel.font=[UIFont systemFontOfSize:12];
cell.textLabel.text=#"A surgeon.";
[cell.contentView addSubview:btn];
return cell;
}
Important note: if you plan on doing any further cell customization, you'll need to remove them manually in the loop as well.

Resources