2011-03-20 13 views
5

Cuando selecciono un jugador en 'didSelectRowAtIndexPath' y agrego una marca de verificación en la fila seleccionada, agrega una marca de verificación adicional.UITableView didSelectRowAtIndexPath agregar marca de verificación adicional al tocar

Si toco row = 0, agrega una marca de verificación a row = 0 y row = 11. Esto significa que dos filas están marcadas por un toque. Si toco la fila = 1, agrega una marca de verificación adicional a la fila = 10, por lo que agrega la marca de verificación 10 filas hacia adelante. Parece que solo agrega la marca de verificación ya que el jugador no entra en la lista de jugadores real.

Cualquier ayuda sería muy apreciada.

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 

UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]; 

NSLog(@"indexPath: %i", indexPath.row); 

// To many players selected 
if (nrOfSelectedPlayers == 6) { //This is max players allowed 
    UIAlertView *alertPlayer = [[UIAlertView alloc] initWithTitle:@"VARNING" 
                  message:@"Du kan maximalt spela \n med sex spelare!" 
                 delegate:self 
               cancelButtonTitle:@"Tillbaka" 
               otherButtonTitles:nil]; 

    [alertPlayer show]; 
    [alertPlayer release]; 
    nrOfSelectedPlayers--; 
    checkDeletePlayer = YES; 
} 
else { 

    // Handle the number of selected players to be able to delete player +6 
    if (checkDeletePlayer == YES) { 
     checkDeletePlayer = NO; 
     nrOfSelectedPlayers++; 
    } 


    if (cell.accessoryType == UITableViewCellAccessoryNone) { 
     cell.accessoryType = UITableViewCellAccessoryCheckmark; 
     [selectedPlayersArray addObject:cell.textLabel.text]; 
     nrOfSelectedPlayers++; 
    } 
    else { 
     cell.accessoryType = UITableViewCellAccessoryNone; 
     selectedPlayer = cell.textLabel.text; 

     for (int oo = 0; oo < nrOfSelectedPlayers; oo++) { 
      if ([selectedPlayersArray objectAtIndex:oo] == cell.textLabel.text) { 
       [selectedPlayersArray removeObjectAtIndex:oo]; 
       nrOfSelectedPlayers--; 
      } 
     } 
     //nrOfSelectedPlayers--; 
    } 
} 
} 
+1

THX tio su pregunta y el fragmento de código me salvó otra pregunta duplicado! – codejunkie

+0

ur welcome dude – PeterK

Respuesta

6

El problema al que se enfrentan es causado por la reutilización de células.

Básicamente, si su UITableView tiene, digamos 50 celdas para mostrar, crea solo 10 y luego reutilícelas a medida que se desplaza hacia abajo/hacia arriba. Así que, independientemente de los cambios que haya hecho a la celda en la fila 0, se volverá a mostrar para la fila 11 ya que TableView usa la misma celda, etc.

Lo que quiere hacer es hacer un seguimiento de los jugadores que han sido seleccionados independientemente de la célula. Puede lograrlo fácilmente creando una colección, digamos NSMutableArray o NSMutableDictionary, que almacenará valores BOOL en objetos NSNumber, por ejemplo.

NSMutableArray *players = [NSMutableArray arrayWithCapacity:50]; 
for (int i = 0; i < 50; i++) { 
    [players addObject:[NSNumber numberWithBool:NO]]; 
} 

Luego, en didSelectRowAtIndexPath: (NSIndexPath *) indexPath hacer en lugar de operar en la célula, simplemente cambiar el valor de un objeto NSNumber correspondiente.

Luego en cellForRowAtIndexPath: (NSIndexPath *) indexPath configura el accesorio de la celda al marcar la entrada correspondiente en la colección de reproductores.

O si usted es muy, muy terca podría reemplazar (NO RECOMENDADO) la siguiente línea de la cellForRowAtIndexPath: (NSIndexPath *) indexPath:

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 

con:

UITableViewCell *cell = nil; 
+0

¿podría mostrar el ejemplo en 'cellForRowAtIndexPath'? – PeterK

+0

arreglado, gracias ALOT :-) – PeterK

+0

De nada. –

2

Para otros que vienen aquí (como yo) para ver por qué su tabla selecciona celdas aleatorias, debe agregar algo como lo siguiente a su celdaForRowAtIndexPath:

// Assume cell not checked; 
[cell setAccessoryType:UITableViewCellAccessoryNone]; 
for (int i = 0; i < checkedIndexPaths.count; i++) { 
    NSUInteger num = [[checkedIndexPaths objectAtIndex:i] row]; 

    if (num == indexPath.row) { 
     [cell setAccessoryType:UITableViewCellAccessoryCheckmark]; 
    } 
} 

Guardo un NSMutableArray llamado checkedIndexPaths para saber qué indexPaths están marcados. Mantener dicha matriz le permite limitar fácilmente la cantidad de celdas que un usuario puede verificar.He aquí un ejemplo de mi didSelectRowAtIndexPath:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]; 

    // uncheck if already checked 
    if (cell.accessoryType == UITableViewCellAccessoryCheckmark) { 
     cell.accessoryType = UITableViewCellAccessoryNone; 
     [checkedIndexPaths removeObject:indexPath]; 
    } 
    else { 
     // make sure no more than 3 are selected 
     if ([checkedIndexPaths count] < 3) { 

      // check row 
      cell.accessoryType = UITableViewCellAccessoryCheckmark; 
      // add it to our list of checked indexes 
      [checkedIndexPaths addObject:indexPath]; 
     } else { 
      UIAlertView* alert = [[UIAlertView alloc] initWithTitle:@"Note" 
                  message:@"You can only select 3 rows." 
                  delegate:nil 
                cancelButtonTitle:@"OK" otherButtonTitles:nil]; 
      [alert show]; 
     } 
    } 
    [tableView deselectRowAtIndexPath:indexPath animated:YES]; 
} 
7

estoy usando guiones gráficos con células dinámico del prototipo para mostrar una lista de los estados que he utilizado algunas de las ideas más arriba antes de encontrar esta solución

Paso 1

@interface StateViewController : UITableViewController 
{ 
    NSMutableArray *checkedIndexPaths; 
} 

Paso 2

(void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    self.states = [[GAIGStateStore sharedInstance]allStates]; 

    //Setup default array to keep track of the checkmarks 
    checkedIndexPaths = [NSMutableArray arrayWithCapacity:self.states.count]; 
    for (int i = 0; i < self.states.count; i++) { 
     [checkedIndexPaths addObject:[NSNumber numberWithBool:NO]]; 
    } 
} 

Paso 3

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{ 

    //This toggles the checkmark 
    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]; 

    if (cell.accessoryType == UITableViewCellAccessoryNone) 
    { 
     cell.accessoryType = UITableViewCellAccessoryCheckmark; 
     //This sets the array 
     [checkedIndexPaths replaceObjectAtIndex:indexPath.row withObject:[NSNumber numberWithBool:YES]]; 

    } else 
    { 
     cell.accessoryType = UITableViewCellAccessoryNone; 
     //This sets the array 
     [checkedIndexPaths replaceObjectAtIndex:indexPath.row withObject:[NSNumber numberWithBool:NO]]; 

    } 


} 

Paso 4

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:stateCell forIndexPath:indexPath]; 

    UILabel *stateLabel = (UILabel *)[cell viewWithTag:1000]; 

    StateProvince *myState = [self.states objectAtIndex:indexPath.row]; 

    stateLabel.text = myState.label; 

    //Now set the check marks 
    // Assume cell not checked; 
    [cell setAccessoryType:UITableViewCellAccessoryNone]; 

    NSNumber *num = [checkedIndexPaths objectAtIndex:indexPath.row]; 


    if (num == [NSNumber numberWithBool:YES]) { 
      [cell setAccessoryType:UITableViewCellAccessoryCheckmark]; 
    } 


    return cell; 
} 
+0

El modelo de código es perfecto, pero una sugerencia de mi parte es que debe comentar la línea dequeueReusableCellWithIdentifier, ya que usará la misma celda para mostrar otras celdas en desplazamiento y también mostrará la opción de marca de verificación allí. – Radix

Cuestiones relacionadas