Add Switch in Uitableview Cell in Swift

Add switch in UITableView cell in Swift

Here is way you can embed a UISwitch on a UITableView cell.

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {        
var cell = tableView.dequeueReusableCell(withIdentifier: "yourcellIdentifire", for: indexPath) as! YourCellClass

//here is programatically switch make to the table view
let switchView = UISwitch(frame: .zero)
switchView.setOn(false, animated: true)
switchView.tag = indexPath.row // for detect which row switch Changed
switchView.addTarget(self, action: #selector(self.switchChanged(_:)), for: .valueChanged)
cell.accessoryView = switchView

return cell
}

here is switch call beck method

func switchChanged(_ sender : UISwitch!){

print("table row switch Changed \(sender.tag)")
print("The switch is \(sender.isOn ? "ON" : "OFF")")
}

@LeoDabus Great! explanation.

Note: if your tableview may have more than one section then You should create a CustomCell subclassing UITableViewCell and configure your accessoryView inside UITableViewCell awakeFromNib method instead of table view cellForRowAt method. When dequeuing the reusable cell cast it to your CustomCell Here is sample from @LeoDabus

Adding a switch to each cell in a UItableview

You need to:

  1. Create a custom UITableViewCell subclass that has @IBOutlets for your text label and UISwitch.
  2. In your table view's storyboard or xib, set the type of the dynamic table view cell to the name of your custom subclass.
  3. In the cell's Attributes inspector, give it a custom reuse identifier.
  4. Drag a UISwitch into the dynamic cell prototype.
  5. Connect the custom cell's outlets to the text label and switch.
  6. In your tableView(_:cellForRowAt:) implementation, instead of instantiating a table cell each time (which is almost never what you want to do), call tableView.dequeueReusableCell(withIdentifier:for:) and pass in the custom reuse identifier that you used in step 3. Cast the returned cell to your custom type, then set the values of the outlets.

Set target for switch in custom UITableViewCell

In your code marked "Strong reference cycle" there is no strong reference cycle, so just go ahead and use it.

Where did you imagine the strong reference cycle was? Was it the use of self as the target? The docs say explicitly:

The control does not retain the object in the target parameter

And that is only to be expected. We'd all be in a fine pickle if you couldn't set self as the action target for a control.

Toggle switch on TableViewCell tap

If I understand it correctly, you just want the highlight to disappear right after the tap.

If that's what you want, you can call directly deselectRow in the didSelectRowAt indexPath method:

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
// Do your custom logic / toggle your switch
}

How to create a UITableViewCell with a UISwitch and get the data?

You could just add the UISwitch in your accessory view. That is the easiest way to do it, not to mention that it looks 'elegant'.

Then, in your tableview controller code, you could just call a selector every time the switch is toggled, or even toggle the switch itself by getting the switch's current status in your controller.

Let know if you'd like a code sample.

---sample code---

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

static NSString *CellIdentifier = @"Cell";

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
//add a switch
UISwitch *switchview = [[UISwitch alloc] initWithFrame:CGRectZero];
cell.accessoryView = switchview;
[switchview release];
}

cell.textLabel.text = [NSString stringWithFormat:@"%d", indexPath.row];

return cell;
}

Then, you could have a method that updates a switch based on changes in your model. You could use anything you want - delegates, notifications, KVO, etc.

Example:

- (void)updateSwitchAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
UISwitch *switchView = (UISwitch *)cell.accessoryView;

if ([switchView isOn]) {
[switchView setOn:NO animated:YES];
} else {
[switchView setOn:YES animated:YES];
}

}

How can I use a switch in a tableview cell?

Clear your IBOutlet connections, connect them again and it will work ;)

How to pass state of UISwitch in prototype cell back to UITableView

First you need to create the call back in table view cell.

 class ProgrammeToogleTableViewCell: UITableViewCell {

@IBOutlet weak var switchUI: UISwitch!

// callback to get action of switch status
var callBackSwitchState:((Bool) -> (Void))?

// Create action for value change event on switch
@IBAction func switchAtValueChanged(programmeToggle: UISwitch) {
callBackSwitchState?(programmeToggle.isOn)
}
}

Now in your cellForRowAt data source method, you need to set the value for this callback that you just created to get the status for your switch:

In your table view class:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> 
UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier:
"ProgrammeToggleTableViewCell", for: indexPath) as? ProgrammeToogleTableViewCell
else { return UITableViewCell() }
cell.tag = indexPath.row

// Implement the callback to get the status of switch:
cell.callBackSwitchState = { isOn in
print("Your Switch status = \(isOn)")

// isOn is your switch status. You can update your object here.
}

// Your other code here ....
return cell
}


Related Topics



Leave a reply



Submit