I have a UISwitch
inside a custom UITableViewCell
(the subclass of which I call RootLabeledSwitchTableCell
).
The cell contains a UILabel
and UISwitch
next to each other.
I have a @property
called keychainSwitch
that points to the switch inside this custom cell:
@interface RootLabeledSwitchTableCell : UITableViewCell {
IBOutlet UILabel *textLabel;
IBOutlet UISwitch *labeledSwitch;
}
@property (nonatomic, retain) IBOutlet UILabel *textLabel;
@property (nonatomic, retain) IBOutlet UISwitch *labeledSwitch;
@end
In my table view delegate, I have added a selector that is called if the switch state is flipped:
- (UITableViewCell *) tableView:(UITableView *)tv cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *CellIdentifier = [NSString stringWithFormat: @"%d:%d", [indexPath indexAtPosition:0], [indexPath indexAtPosition:1]];
UITableViewCell *cell = [tv dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
switch (indexPath.section) {
case(kMyFirstSection): {
switch (indexPath.row) {
case(kMyFirstSectionFirstRow) {
[cellOwner loadMyNibFile:@"RootLabeledSwitchTableCell"];
cell = (RootLabeledSwitchTableCell *)cellOwner.cell;
self.keychainSwitch = [(RootLabeledSwitchTableCell *)cell labeledSwitch];
[self.keychainSwitch addTarget:self action:@selector(keychainOptionSwitched) forControlEvents:UIControlEventValueChanged];
break;
}
// ...
}
}
// ...
}
}
So this selector works correctly:
- (void) keychainOptionSwitched {
NSLog(@"Switched keychain option from %d to %d", ![self.keychainSwitch isOn], [self.keychainSwitch isOn]);
}
However, I cannot use the UISwitch
instance's -setOn:animated:
method to initialize its initial state:
- (void) updateInterfaceState {
BOOL isFirstTimeRun = [[[NSUserDefaults standardUserDefaults] objectForKey:kIsFirstTimeRunKey] boolValue];
if (isFirstTimeRun) {
[self.keychainSwitch setOn:NO animated:NO];
}
}
From testing, self.keychainSwitch
is nil
which is causing -setOn:animated
to do nothing, but I can still operate the switch and the NSLog
statement will correctly print the switch state changes, e.g.:
[Session started at 2009-08-24 07:04:56 -0700.]
2009-08-24 07:04:58.489 MyApp[29868:20b] keychain switch is: nil
2009-08-24 07:05:00.641 MyApp[29868:20b] Switched keychain option from 1 to 0
2009-08-24 07:05:01.536 MyApp[29868:20b] Switched keychain option from 0 to 1
2009-08-24 07:05:02.928 MyApp[29868:20b] Switched keychain option from 1 to 0
Is there something I am missing about setting self.keychainSwitch
in the UITableView
delegate method?
I spent ages fiddling around with custom UITableViewCells with a simple label and switch on it before I discovered I could just add a UISwitch as an accessory view. You're probably aware of this anyway, and want the custom cell for other reasons, but just in case I wanted to mention this!
You do this as follows (in the -tableView:cellForRowAtIndexPath method):
UISwitch *mySwitch = [[[UISwitch alloc] initWithFrame:CGRectZero] autorelease];
cell.accessoryView = mySwitch;
The accessoryView bit also takes care of the sizing and positioning so we can get away with CGRectZero.
You're then able to use the system control event and setOn method as follows (note we cast it as the UISwitch pointer that we know it is):
[(UISwitch *)cell.accessoryView setOn:YES]; // Or NO, obviously!
[(UISwitch *)cell.accessoryView addTarget:self action:@selector(mySelector)
forControlEvents:UIControlEventValueChanged];
Hope that helps!