Desplazamiento de UITableview cambia las imágenes de UIButton, problema de desplazamiento de UITableview

Lo que estoy haciendo es que tengo una vista UITableview y agregué UIButton como una vista personalizada. Estoy dando label a cada button y la label se recibió en el método de acción. Cuando presiono el button cambia las imágenes para el button seleccionado y no seleccionado, pero cuando lo desploop, llegará al estado normal.

Esta es mi celda para la fila en el método de índice

 static NSString *CellIdentifier = @"Cell4"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if (cell == nil) { cell = [self tableviewCellWithReuseIdentifierFollowing:CellIdentifier]; } followingButton = [UIButton buttonWithType:UIButtonTypeCustom]; [followingButton addTarget:self action:@selector(followingButtonpressed:)forControlEvents:UIControlEventTouchUpInside]; [followingButton setImage:[UIImage imageNamed:@"following12.png"] forState:UIControlStateNormal]; followingButton.frame = CGRectMake(220.0 ,20.0, 100, 40.0); [cell.contentView addSubview:followingButton]; NSLog(@"row--%d",indexPath.row); followingButton.tag=indexPath.row; NSLog(@"followingButton.tag--%d",followingButton.tag); [self configureCellFollowing:cell forIndexPath:indexPath]; return cell; } ================== //Here is the action method -(void)followingButtonpressed:(id)sender { NSLog(@"sender tag --%d",[sender tag]); UIButton *btnPly = (UIButton *)sender; if([btnPly isSelected]) { [btnPly setSelected:NO]; [btnPly setImage:[UIImage imageNamed:@"following12.png"] forState:UIControlStateNormal]; } else { [btnPly setSelected:YES]; [btnPly setImage:[UIImage imageNamed:@"following_off12.png"] forState:UIControlStateNormal]; } } 

Nota: Esta celda de creación de código para cada fila de datos (celda No reutilizar)

Necesita cambiar solo como se describe, puede ser útil para usted

 NSString *CellIdentifier = [NSString stringWithFormat:@"S%1dR%1d",indexPath.section,indexPath.row]; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 

puede resolver tu problema 🙂

La razón por la que sus botones "reinician" es porque tableView: cellForRowAtIndexPath se llama varias veces (siempre que una celda está a punto de ser visible).

Cada vez que se recibe esta llamada, se reinicializa el button y se restablece la image a following12.png (el estado pnetworkingeterminado). Es por eso que al desplazarte, los botones parecen reiniciarse.

No puede confiar en la propia celda para conservar el estado porque la celda se reiniciará cada vez. Necesita mover su estado a otro lugar (como en una variable de instancia de matriz). Luego, cuando debe configurar una nueva celda en tableView: cellForRowAtIndexPath, puede inicializarla en el estado apropiado (basado en la matriz).

Por lo tanto, cree una variable de instancia NSMutableArray llamada myStateArray (o lo que sea) para almacenar sus estados de button, luego su cellForRowAtIndexPath debería parecerse más a:

 static NSString *CellIdentifier = @"Cell4"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if (cell == nil) { cell = [self tableviewCellWithReuseIdentifierFollowing:CellIdentifier]; } followingButton = [UIButton buttonWithType:UIButtonTypeCustom]; [followingButton addTarget:self action:@selector(followingButtonpressed:)forControlEvents:UIControlEventTouchUpInside]; // -- Fetch the state from your array BOOL buttonPressed = [[self.myStateArray objectAtIndex:indexPath.row] boolValue]; // -- Initialize the button state correctly [followingButton setSelected:buttonPressed]; if (buttonPressed) { [followingButton setImage:[UIImage imageNamed:@"following12.png"] forState:UIControlStateNormal]; } else { [followingButton setImage:[UIImage imageNamed:@"following_off12.png"] forState:UIControlStateNormal]; } followingButton.frame = CGRectMake(220.0 ,20.0, 100, 40.0); [cell.contentView addSubview:followingButton]; NSLog(@"row--%d",indexPath.row); followingButton.tag=indexPath.row; NSLog(@"followingButton.tag--%d",followingButton.tag); [self configureCellFollowing:cell forIndexPath:indexPath]; return cell; } 

Luego, en su button presione, asegúrese de save el estado:

 -(void)followingButtonpressed:(id)sender { // -- Save the state [self.myStateArray insertObject:[NSNumber numberWithBool:[btnPly isSelected]] atIndex:[sender tag]]; NSLog(@"sender tag --%d",[sender tag]); UIButton *btnPly = (UIButton *)sender; if([btnPly isSelected]) { [btnPly setSelected:NO]; [btnPly setImage:[UIImage imageNamed:@"following12.png"] forState:UIControlStateNormal]; } else { [btnPly setSelected:YES]; [btnPly setImage:[UIImage imageNamed:@"following_off12.png"] forState:UIControlStateNormal]; } } 

Como entiendo desde el código, crea UIButton cada vez que UITableView solicita celda. En ambos casos, si crea una nueva celda o si usa una celda. Luego, crea y agrega un button más cada vez que ya está creado. Mueva la creación del button a la creación de celdas if su método cellForRowAtIndexPath debería ser similar a

 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *CellIdentifier = @"Cell4"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if (cell == nil) { cell = [self tableviewCellWithReuseIdentifierFollowing:CellIdentifier]; followingButton = [UIButton buttonWithType:UIButtonTypeCustom]; [followingButton addTarget:self action:@selector(followingButtonpressed:)forControlEvents:UIControlEventTouchUpInside]; [followingButton setImage:[UIImage imageNamed:@"following12.png"] forState:UIControlStateNormal]; followingButton.frame = CGRectMake(220.0 ,20.0, 100, 40.0); [cell.contentView addSubview:followingButton]; } NSLog(@"row--%d",indexPath.row); followingButton.tag=indexPath.row; NSLog(@"followingButton.tag--%d",followingButton.tag); [self configureCellFollowing:cell forIndexPath:indexPath]; return cell; } 

Pero esto no será una solución competitiva de su problema. Como probablemente usted sepa, UITableView utiliza células "reutilizables" para disminuir el uso de la memory del sistema. Utiliza solo la cantidad de células que es necesario mostrar en este momento. Por lo tanto, en la tabla con 100 celdas, se crearán aproximadamente 10. Y todos no almacenarán el estado correcto de todos los botones presionados / no comprimidos. Para lograr un comportamiento correcto, debe rechazar el uso de tags y usar alguna lógica del model. La forma más fácil: NSMutableArray donde almacenará los estados de los botones. En followingButtonpressed: método establecerá el object correcto en YES / NO y en cellForRowAtIndexPath leerá este valor. Marque el siguiente código

 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *CellIdentifier = @"Cell4"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if (cell == nil) { cell = [self tableviewCellWithReuseIdentifierFollowing:CellIdentifier]; followingButton = [UIButton buttonWithType:UIButtonTypeCustom]; [followingButton addTarget:self action:@selector(followingButtonpressed:)forControlEvents:UIControlEventTouchUpInside]; [followingButton setImage:[UIImage imageNamed:@"following12.png"] forState:UIControlStateNormal]; followingButton.frame = CGRectMake(220.0 ,20.0, 100, 40.0); [cell.contentView addSubview:followingButton]; BOOL isSelected = [[statesArray objectAtIndex:btnPly.tag] boolValue]; [self setState:isSelected forButton:followingButton]; } NSLog(@"row--%d",indexPath.row); followingButton.tag=indexPath.row; NSLog(@"followingButton.tag--%d",followingButton.tag); [self configureCellFollowing:cell forIndexPath:indexPath]; return cell; } -(void)followingButtonpressed:(id)sender { NSLog(@"sender tag --%d",[sender tag]); UIButton *btnPly = (UIButton *)sender; BOOL isSelected = [[statesArray objectAtIndex:btnPly.tag] boolValue]; [statesArray replaceObjectAtIndex:btnPly.tag withObject:[NSNumber numberWithBool:!isSelected]]; if(isSelected) { [self setState:NO forButton:btnPly]; } else { [self setState:YES forButton:btnPly]; } } - (void) setState:(BOOL)state forButton:(UIButton *)button { if(state) { [button setSelected:NO]; [button setImage:[UIImage imageNamed:@"following12.png"] forState:UIControlStateNormal]; } else { [button setSelected:YES]; [button setImage:[UIImage imageNamed:@"following_off12.png"] forState:UIControlStateNormal]; } } 

Donde statesArray es

 NSMutableArray *statesArray = [NSMutableArray new]; 

y tienes que crearlo e inicializarlo en algún lugar de tu class. El recuento de objects en statesArray debe ser el mismo que el recuento de las celdas int tableView.

Esto se debe a que cada vez que se desplaza, este código invoca

 [followingButton setImage:[UIImage imageNamed:@"following12.png"] forState:UIControlStateNormal]; 

así que mira ahora

 static NSString *CellIdentifier = @"Cell4"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if (cell == nil) { cell = [self tableviewCellWithReuseIdentifierFollowing:CellIdentifier]; followingButton = [UIButton buttonWithType:UIButtonTypeCustom]; [followingButton addTarget:self action:@selector(followingButtonpressed:)forControlEvents:UIControlEventTouchUpInside]; [followingButton setImage:[UIImage imageNamed:@"following12.png"] forState:UIControlStateNormal]; followingButton.frame = CGRectMake(220.0 ,20.0, 100, 40.0); [cell.contentView addSubview:followingButton]; [self configureCellFollowing:cell forIndexPath:indexPath]; } return cell; }