Reputation: 6794
I am trying to put a UISwitch
into a UITableView
. I have looked at this question here and here. Since the table view reuses cells I need to save the state of the cells. I achieve this by having a NSMutableDictionary
where the row of the cell maps the state (true or false) of the UISwitch. The problem I am running into is identifying the index of the UISwitch in the TableView. I think something is wrong with the @selector statement. This has been driving me crazy for the past 2 hours. Is this the right way to do it and why do I change the state of any of the UISwitch it always reports with the same log message (see below). Any help is greatly appreciated. Here is some snippets of my code ....
cellForRowAtIndexPath
//Need to construct
if (cell == nil)
{
cell = [[[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
UISwitch *temp = [[[UISwitch alloc] initWithFrame:CGRectZero] autorelease];
//Add a callback when the value is changed
[temp addTarget:self action:@selector(switchButtonChanged:forEvent:) forControlEvents:UIControlEventValueChanged];
//Set the acessory view to the UISwitch
cell.accessoryView = temp;
}
Callback Method
- (void)switchButtonChanged:(id)sender forEvent:(UIEvent *)event
{
UISwitch *tempSwitch = (UISwitch *) sender;
NSIndexPath *indexPath = [tableView indexPathForRowAtPoint:[[[event touchesForView:sender] anyObject] locationInView:tableView]];
NSNumber *isChecked = [[[NSNumber alloc] initWithBool:tempSwitch.on] autorelease];
NSNumber *row = [[[NSNumber alloc] initWithInteger:indexPath.row] autorelease];
[self.selectedItems setObject:isChecked forKey:row];
NSLog(@"Row %@ is now %@", row, [self.selectedItems objectForKey:row]);
}
Log
Row 0 is now (null)
Row 0 is now (null)
Row 0 is now (null)
Upvotes: 2
Views: 988
Reputation: 17481
Generally, the easiest way to deal with this is to stick something directly into the UISwitch that you create, so that you can grab the information directly from the switch.
Conveniently, the UISwitch, being a subclass of UIControl, and thus UIView, has a tag attribute, which is an integer that you can use to store any value you need.
You'll set the tag value on the cell each time that the cellForRowAtPath: is called (not just when a new cell is created, but also when an existing cell is reused) and also make sure you change the state of the UISwitch.
iOS will make sure that new cells are created and existing ones are reused, so you don't have to worry about over-using or duplicates.
In the callback method, pull the "row" value out of the tag (where you stored it in the cellForRowAtPath:) and use that to access the dictionary.
Also, as mentioned by previous commenters, make sure you have initialized both the NSMutableDictionary and any default values you want in there.
Hope this helps.
Upvotes: 2
Reputation: 44633
The most likely reason is that self.selectedItems
is nil
. You might not have initialized it. You might want to put a
self.selectedItems = [NSMutableDictionary dictionary];
in the viewDidLoad
method.
Upvotes: 1