¿Cómo puedo incrustar un UISwitch
en una UITableView
celda? Se pueden ver ejemplos en el menú de configuración.
Mi solución actual:
UISwitch *mySwitch = [[[UISwitch alloc] init] autorelease];
cell.accessoryView = mySwitch;
¿Cómo puedo incrustar un UISwitch
en una UITableView
celda? Se pueden ver ejemplos en el menú de configuración.
Mi solución actual:
UISwitch *mySwitch = [[[UISwitch alloc] init] autorelease];
cell.accessoryView = mySwitch;
Respuestas:
Establecerlo como accesorio de vista suele ser el camino a seguir. Puede configurarlo en tableView:cellForRowAtIndexPath:
Es posible que desee utilizar objetivo / acción para hacer algo cuando se activa el interruptor. Al igual que:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
switch( [indexPath row] ) {
case MY_SWITCH_CELL: {
UITableViewCell *aCell = [tableView dequeueReusableCellWithIdentifier:@"SwitchCell"];
if( aCell == nil ) {
aCell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:@"SwitchCell"] autorelease];
aCell.textLabel.text = @"I Have A Switch";
aCell.selectionStyle = UITableViewCellSelectionStyleNone;
UISwitch *switchView = [[UISwitch alloc] initWithFrame:CGRectZero];
aCell.accessoryView = switchView;
[switchView setOn:NO animated:NO];
[switchView addTarget:self action:@selector(switchChanged:) forControlEvents:UIControlEventValueChanged];
[switchView release];
}
return aCell;
}
break;
}
return nil;
}
- (void)switchChanged:(id)sender {
UISwitch *switchControl = sender;
NSLog( @"The switch is %@", switchControl.on ? @"ON" : @"OFF" );
}
switchView.tag = indexPath.row
para detectar qué cambio de fila se cambió para rápido
if (indexPath.row == 0) {//If you want UISwitch on particular row
UISwitch *theSwitch = [[UISwitch alloc] initWithFrame:CGRectZero];
[cell addSubview:theSwitch];
cell.accessoryView = theSwitch;
}
initWithFrame
? ¿Por qué lo usa addSubview
? switch
no se puede utilizar como nombre de variable.
Puede preparar la celda en Interfacebuilder, vincularla a un IBOutlet de su Viewcontroller y devolverla cuando la vista de tabla solicite la fila adecuada.
En su lugar, puede crear un xib separado para la celda (nuevamente con IB) y cargarlo usando UINib al crear las celdas.
Finalmente, puede crear el conmutador mediante programación y agregarlo a la vista de contenido o vista de accesorios de sus celdas.
Cuál se adapta mejor a ti depende en gran medida de lo que te gusta hacer. Si el contenido de las vistas de tabla es fijo (para una página de configuración, etc.), los dos primeros podrían funcionar bien, si el contenido es dinámico, preferiría la solución programática. Sea más específico en lo que le gustaría hacer, esto facilitaría la respuesta a su pregunta.
Esta es una solución más completa donde se apaga y enciende en la capa de vista (UITableViewCell) y reenvía los eventos al delegado de tableView a través de didSelect
y didDeselect
:
class CustomCell: UITableViewCell {
private lazy var switchControl: UISwitch = {
let s = UISwitch()
s.addTarget(self, action: #selector(switchValueDidChange(_:)), for: .valueChanged)
return s
}()
override func awakeFromNib() {
self.accessoryView = switchControl
self.selectionStyle = .none // to show the selection style only on the UISwitch
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
(self.accessoryView as? UISwitch)?.isOn = selected
}
@objc private func switchValueDidChange(_ sender: UISwitch) { // needed to treat switch changes as if the cell was selected/unselected
guard let tv = self.superview as? UITableView, let ip = tv.indexPath(for: self) else {
fatalError("Unable to cast self.superview as UITableView or get indexPath")
}
setSelected(sender.isOn, animated: true)
if sender.isOn {
tv.delegate?.tableView?(tv, didSelectRowAt: ip)
} else {
tv.delegate?.tableView?(tv, didDeselectRowAt: ip)
}
}
}
Y en tu delegado
func tableView(_ tableView: UITableView, shouldHighlightRowAt indexPath: IndexPath) -> Bool {
return false // to disable interaction since it happens on the switch
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { // to make sure it is rendered correctly when dequeuing:
// stuff
if isSelected { // stored value to know if the switch is on or off
tableView.selectRow(at: indexPath, animated: true, scrollPosition: .none)
} else {
tableView.deselectRow(at: indexPath, animated: true)
}
// more stuff
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
// do your thing when selecting
}
func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
// do your thing when deselecting
}