Reputation: 35783
I have designed a Table view , For Select Followers list to send message, so there I can select some followers and then send them message on twitter.
I am using UITable View with UITableViewCellAccessoryCheckmark to make this.
But when I scroll down table, the checked rows get unchecked every time.
I have decleard table view and an array for selected followers in FollowersListView.h
@interface FollowersListView : UIViewController<UITableViewDelegate,UITableViewDataSource>{
IBOutlet UITableView *tableFollowers;
NSMutableArray *listFollowrsName;
NSMutableArray *listSelectedFollowrsId;
}
@property(nonatomic,retain) NSMutableArray *listFollowrsName;
@property(nonatomic,retain) NSMutableArray *listSelectedFollowrsId;
@end
and my tableview code is like this in FollowersListView.m file
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return [listFollowrsName count];
}
- (UITableViewCell *)tableView:(UITableView *)tv cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tv dequeueReusableCellWithIdentifier:@"CellWithSwitch"];
//if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"CellWithSwitch"] autorelease];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell.textLabel.font = [UIFont systemFontOfSize:14];
//cell.accessoryType = UITableViewCellAccessoryCheckmark;
cell.accessoryType = UITableViewCellStyleDefault;
//}
NSString *cellValue = [listFollowrsName objectAtIndex:indexPath.row];
cell.textLabel.text = cellValue;
return cell;
}
//to select a row
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)path {
UITableViewCell *cell = [tableView cellForRowAtIndexPath:path];
if (cell.accessoryType == UITableViewCellAccessoryCheckmark) {
cell.accessoryType = UITableViewCellAccessoryNone;
NSLog(@"row is un-checked %@",[NSNumber numberWithInt:path.row]);
[listSelectedFollowrsId removeObject:[NSNumber numberWithInt:path.row]];
NSLog(@"Now selected person are%@",listSelectedFollowrsId);
} else {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
NSLog(@"row is checked %@",[NSNumber numberWithInt:path.row]);
[listSelectedFollowrsId addObject:[NSNumber numberWithInt:path.row]];
NSLog(@"Now selected person are%@",listSelectedFollowrsId);
}
}
I guess I need to load every cell as per the already stored selected list but not getting how to do.
Can anyone guide where I'm doing wrong, Any help would be appreciated
Edit
@Novarg
I have declared "listSelectedFollowrsId" as a NSMutable Array in .h file and initialized in viewDidLoad method then adding/removing values in didSelectRowAtIndexPath method to manage selected rows.
Upvotes: 1
Views: 2172
Reputation: 885
you can use this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil] autorelease];
cell.backgroundColor=[UIColor clearColor];
cell.selectionStyle=UITableViewCellSelectionStyleNone;
cell.accessoryType=UITableViewCellAccessoryNone;
}
else
{
UIView *subview;
while ((subview= [[[cell contentView]subviews]lastObject])!=nil)
[subview removeFromSuperview];
}
NSString *cellValue = [listFollowrsName objectAtIndex:indexPath.row];
cell.textLabel.text = cellValue;
return cell;
}
Upvotes: 1
Reputation: 7450
The thing is that you create a new cell every time that you scroll. The if (cell == nil)
condition must be there, otherwise you will just keep on re-writing the cell over and over again.
Try the following:
- (UITableViewCell *)tableView:(UITableView *)tv cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tv dequeueReusableCellWithIdentifier:@"CellWithSwitch"];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"CellWithSwitch"] autorelease];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell.textLabel.font = [UIFont systemFontOfSize:14];
cell.accessoryType = UITableViewCellStyleDefault;
}
NSString *cellValue = [listFollowrsName objectAtIndex:indexPath.row];
cell.textLabel.text = cellValue;
return cell;
}
It might not work, I'm using a windows machine right now, so can't compile the code and test it myself now.
Hope it helps
EDIT
If it doesn't solve the problem I'd also add a variable(probably an NSMutableDictionary
) to keep a record of the names that have been "checked". Using that you can add the following just before return cell;
in cellForRowAtIndexPath:
method:
if ([[theDictionary objectForKey:/*your key here, can be anything*/]isEqualToString:/*string or whatever, just make sure that the checked ones are different from the unchecked ones*/])
cell.accessoryType = UITableViewCellAccessoryCheckmark;
else
cell.accessoryType = UITableViewCellAccessoryNone;
EDIT 2
Here's what you should add right before return cell;
(didn't see the listSelectedFollowrsId
array before):
cell.accessoryType = UITableViewCellAccessoryNone;
for (int i = 0; i < [listSelectedFollowrsId count]; i++) {
if ([[listSelectedFollowrsId objectAtIndex:i]intValue] == indexPath.row) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
}
That will set the accessory to checkmark if the row has been previously tapped.
Upvotes: 5
Reputation: 3518
In cellForRowAtIndexPath you are always setting it to unchecked. You need to test whether that row is in the your list of selected followers, if so set the accessory accordingly.
This is all due to cell reuse to keep memory consumption low even for tables with thousands of rows.
Upvotes: 0
Reputation: 17186
Its because when you scroll the table, cellForRowAtIndexPath gets called.
In this function you are creating the cell again and again. So, your checkmarks are getting removed which you have marked in didSelectRowAtIndexPath.
Refer this link for detailed example of tableview.
Upvotes: 0