Question

I want a UISwitch within a TableViewCell to change the text from 'Active' to 'Disabled' and vice versa when switched but when the switch changes, all the data in my table view disappears. I'm using 'reload data' since I do not know how to change a specific cell's text.

FYI, 'current item' is a core data entity with a BOOL property 'itemEnabled'.

The switch is only visible during 'editing mode'.

I have a UISwitch in a table view cell within my 'detail view controller':

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

UITableViewCell *cell = nil;
NSString *cellDetail = nil;

        static NSString *EnabledCellIdentifier = @"Enabled";
        cell = [tableView dequeueReusableCellWithIdentifier:EnabledCellIdentifier];
        if (cell == nil) {
            cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:EnabledCellIdentifier] autorelease];
            UISwitch* actSwitch = [[UISwitch alloc] initWithFrame:CGRectZero];
            [cell setEditingAccessoryView:actSwitch];
            [actSwitch addTarget:self action:@selector(actSwitchChanged:) forControlEvents:UIControlEventValueChanged];
            if ([[currentItem valueForKey:@"itemEnabled"] boolValue]) {
                cellDetail = @"Active";
                actSwitch.on = YES;
            } else {
                cellDetail = @"Disabled";
                actSwitch.on = NO;
            }
            [actSwitch release];

    cell.textLabel.text = cellDetail;

return cell;

}

I have a method to receive the action:

- (void)actSwitchChanged:(id)sender {

UISwitch* swEnabled = (UISwitch*)sender;

NSManagedObjectContext* itemContext = [currentItem managedObjectContext];

currentItem.itemEnabled = [NSNumber numberWithBool:swEnabled.on];

NSError *error = nil;
if (![itemContext save:&error]) {

    NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
    abort();
}

}

Was it helpful?

Solution 3

So I subclassed UISwtich and included property for storing the cell's index path, which can then be used in the action method:

- (void)actSwitchChanged:(id)sender {

TLSwitchInCell* swEnabled = (TLSwitchInCell*)sender;

currentItem.itemEnabled = [NSNumber numberWithBool:swEnabled.on];

UITableViewCell* theCell = [self.tableView cellForRowAtIndexPath:swEnabled.cellIndexPath];

theCell.textLabel.text = swEnabled.on ? @"Active" : @"Disabled";

}

OTHER TIPS

Here is an approach to getting the cell from within the action method that does not require subclassing UISwitch:

- (void)switchAction:(id)sender {

     // Cast the sender as a UISwitch
     UISwitch *aSwitch = (UISwitch *)sender;

     // Cast the superview of aSwitch to a UITableViewCell
     UITableViewCell *cell = (UITableViewCell *)aSwitch.superview;

     // You could get an indexPath as follows (though you don't need it in this case)
     NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];    

     // Set the text of the label in your cell
     cell.textLabel.text = aSwitch.on ? @"Active"; : @"Disabled";
}

You can get a specific cell with -[UITableView cellForRowAtIndexPath:]. You just need to know the index path of the cell (also note that you are asking the tableview for the cell, not calling the delegate method).

Another variation on a theme! If you have lots of settings fields with switch buttons you can use something like this to grab the label text associated with the switch button that was trigger! You can set the text using usual methods!

@IBAction func switch(sender: UISwitch) {
  let labelIndex = sender.superview!.subviews.indexOf({$0 is UILabel})
  NSLog("The text from the label associated with this switch is %@",
  (sender.superview!.subviews[labelIndex!] as! UILabel).text!)
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top