uitableviewcontroller uitableviewcell number ios uitableview

ios - uitableviewcell - uitableviewcontroller



✔ Marca de verificación la fila seleccionada en UITableViewCell (12)

Soy un novato en el desarrollo de iOS. Quiero agregar una marca de verificación a mi UITableViewCell cuando se selecciona. La marca de verificación debe eliminarse cuando se selecciona otra fila. ¿Cómo haría esto?


Asumiendo que estás en una clase que hereda de UITableViewController , este es el truco en Swift 3:

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { // Add a visual cue to indicate that the cell was selected. self.tableView.cellForRow(at: indexPath)?.accessoryType = .checkmark } override func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? { // Invoked so we can prepare for a change in selection. // Remove previous selection, if any. if let selectedIndex = self.tableView.indexPathForSelectedRow { // Note: Programmatically deslecting does NOT invoke tableView(:didSelectRowAt:), so no risk of infinite loop. self.tableView.deselectRow(at: selectedIndex, animated: false) // Remove the visual selection indication. self.tableView.cellForRow(at: selectedIndex)?.accessoryType = .none } return indexPath }


Cuando una celda seleccionada (con la marca de verificación seleccionada nuevamente), simplemente elimine la selección.

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath*)indexPath { BOOL isSelected = ([tableView cellForRowAtIndexPath:indexPath].accessoryType == UITableViewCellAccessoryCheckmark); if(isSelected){ [tableView cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryNone; [tableView deselectRowAtIndexPath:indexPath animated:YES]; //this won''t trigger the didDeselectRowAtIndexPath, but it''s always a good idea to remove the selection }else{ [tableView cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryCheckmark; } } - (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath*)indexPath { [tableView cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryNone; }

Prima:

Utilice self.tableView.indexPathForSelectedRow para detectar indexPath para la celda seleccionada


Descubrí que volver a cargar los datos interrumpe la anulación de la selección de forma desagradable.

Esta implementación de Swift agrega / quita marcas de verificación y deselecciona la fila:

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { if self.lastSelection != nil { self.myTableView.cellForRowAtIndexPath(self.lastSelection)?.accessoryType = .None } self.myTableView.cellForRowAtIndexPath(indexPath)?.accessoryType = .Checkmark self.lastSelection = indexPath self.myTableView.deselectRowAtIndexPath(indexPath, animated: true) }

donde lastSelection se declara como var lastSelection: NSIndexPath!

No se necesita actividad adicional en cellForRowAtIndexPath . No debería ser difícil de replicar en Obj-C.


El código mencionado arriba solo funciona con la única selección . Este código siguiente seguramente funcionará para múltiples selecciones .

- (void)viewDidLoad { arrSelectionStatus =[NSMutableArray array]; //arrSelectionStatus holds the cell selection status for (int i=0; i<arrElements.count; i++) { //arrElements holds those elements which will be populated in tableview [arrSelectionStatus addObject:[NSNumber numberWithBool:NO]]; } } -(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"]; if (cell==nil) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"Cell"]; } cell.textLabel.text=[arrElements objectAtIndex:indexPath.row]; if ([[arrSelectionStatus objectAtIndex:indexPath.row] boolValue] == YES) cell.accessoryType = UITableViewCellAccessoryCheckmark; else cell.accessoryType = UITableViewCellAccessoryNone; return cell; } -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]; cell.accessoryType = UITableViewCellAccessoryCheckmark; [arrSelectionStatus replaceObjectAtIndex:indexPath.row withObject:[NSNumber numberWithBool:YES]]; } -(void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath{ UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]; cell.accessoryType = UITableViewCellAccessoryNone; [arrSelectionStatus replaceObjectAtIndex:indexPath.row withObject:[NSNumber numberWithBool:NO]]; }


En su método UITableViewDatasource:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *CellIdentifier = @"Cell"; UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if(cell == nil ) { cell =[[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease]; } if ([indexPath compare:self.lastIndexPath] == NSOrderedSame) { cell.accessoryType = UITableViewCellAccessoryCheckmark; } else { cell.accessoryType = UITableViewCellAccessoryNone; } return cell; } // UITableView Delegate Method -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { self.lastIndexPath = indexPath; [tableView reloadData]; }

Y lastIndexPath es una property(strong) NSIndexPath* lastIndexPath;


Es mejor enfrentar este problema desde otra dirección. Ponga todo el trabajo en los mecanismos internos de UIKit y mueva la implementación a UITableViewCell:

@implementation MYTableViewCell - (void)setSelected:(BOOL)selected animated:(BOOL)animated { [super setSelected:selected animated:animated]; self.accessoryType = selected ? UITableViewCellAccessoryCheckmark : UITableViewCellAccessoryNone; } - (void)prepareForReuse { [super prepareForReuse]; self.accessoryType = UITableViewCellAccessoryNone; } @end


Las respuestas anteriores no funcionan si reutilizó la celda para una gran cantidad de datos. En el desplazamiento, puede ver marcas de verificación repetidas. Para evitar el uso debajo de los pasos:

  1. declarar en la variable: var indexNumber: NSInteger = -1

  2. Agregue el código siguiente en cellforRowAtIndexPath:

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{ if indexNumber == indexPath.row{ cell.accessoryType = .checkmark }else{ cell.accessoryType = .none } }

  3. Y en didselectAtIndexpath agrega el siguiente código:

anular func tableView (_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { tableView.cellForRow(at: indexPath as IndexPath)?.accessoryType = .checkmark indexNumber = indexPath.row } override func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) { tableView.cellForRow(at: indexPath as IndexPath)?.accessoryType = .none }


No use [tableview reloadData]; // es un martillo.

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { [tableView cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryCheckmark; } -(void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath { [tableView cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryNone; }


Para establecer una marca de verificación:

UITableViewCell *cell = ...; cell.accessoryType = UITableViewCellAccessoryCheckmark;

Para seleccionar / deseleccionar una celda:

[cell setSelected:TRUE animated:TRUE]; // select [cell setSelected:FALSE animated:TRUE]; // deselect

Para anular la selección de la celda anterior, use un NSIndexPath * lastSelected ivar para rastrear la última celda seleccionada:

- (void)tableView:(UITableView*)tableView didSelectRowAtIndexPath:(NSIndexPath*)indexPath { if (self.lastSelected==indexPath) return; // nothing to do // deselect old UITableViewCell *old = [self.tableView cellForRowAtIndexPath:self.lastSelected]; old.accessoryType = UITableViewCellAccessoryNone; [old setSelected:FALSE animated:TRUE]; // select new UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath]; cell.accessoryType = UITableViewCellAccessoryCheckmark; [cell setSelected:TRUE animated:TRUE]; // keep track of the last selected cell self.lastSelected = indexPath; }


Simplemente llame didSelectRowAtIndexPath método didSelectRowAtIndexPath cuando seleccione cualquier fila para Mostrar CheckMark y seleccione la fila de marca de verificación para ocultar CheckMark.

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath: (NSIndexPath *)indexPath { [tableView deselectRowAtIndexPath:indexPath animated:true]; NSLog(@"touch"); UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]; if (cell.accessoryType == UITableViewCellAccessoryNone) { cell.accessoryType = UITableViewCellAccessoryCheckmark; } else { cell.accessoryType = UITableViewCellAccessoryNone; } }


pequeño error

// deselect old UITableViewCell *old = [self.tableView cellForRowAtIndexPath:self.lastSelected]; cell.accessoryType = UITableViewCellAccessoryNone; [cell setSelected:FALSE animated:TRUE];

tiene que leer

// deselect old UITableViewCell *old = [self.tableView cellForRowAtIndexPath:self.lastSelected]; old.accessoryType = UITableViewCellAccessoryNone; [old setSelected:FALSE animated:TRUE];

y también en el

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { if (indexPath.row == [previouslySelected intValue]) { cell.accessoryType = UITableViewCellAccessoryCheckmark; selectedIndex = indexPath; [cell setSelected:YES animated:YES]; } else { cell.accessoryType = UITableViewCellAccessoryNone; [cell setSelected:NO animated:YES]; } }

donde previamente Seleccionado es su ivar local, etc. de esa manera, si recarga con un índice seleccionado, también se anula cuando examina las selecciones posibles.


extension ViewController : UITableViewDelegate,UITableViewDataSource { func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return self.dataArray.count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) cell.textLabel?.text = dataArray[indexPath.row] if selectedData.contains(dataArray[indexPath.row]) { cell.accessoryType = .checkmark }else{ cell.accessoryType = .none } return cell } func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { if selectedData.contains(dataArray[indexPath.row]) { selectedData.removeLast() tableView.cellForRow(at: indexPath)?.accessoryType = .none }else { selectedData.removeAll() selectedData.append(dataArray[indexPath.row]) tableView.cellForRow(at: indexPath)?.accessoryType = .checkmark } print(selectedData) } func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) { tableView.cellForRow(at: indexPath)?.accessoryType = .none } }

basado en la vista de tabla dataArray formada ... similarmente, tomé una matriz vacía, y cada vez que el usuario toca una celda, basado en indexValue de dataArray, almacené ese objeto en selectedDataArray

En cuanto a la pregunta, es como ... Una pregunta tiene múltiples opciones (Respuestas), pero finalmente solo una o ninguna respuesta será un resultado

Del mismo modo, solo una celda debe mostrar una marca de verificación y las celdas restantes deben estar deseleccionadas ... en algún caso puede deseleccionar su respuesta ... Espero que esta sea la mejor respuesta a esta pregunta