ios - ¿Cómo cambiar el título de UIButton que se colocó en la celda del prototipo?
objective-c uitableview (3)
Tengo TableView con tipos de celdas personalizados. En prototipo celular tengo 3 botones. Quiero poder cambiar el título del botón cuando presioné otro. Estoy intentando esto:
- (IBAction) doSomething:(id) sender {
CGPoint hitPoint = [sender convertPoint:CGPointZero toView:self.myTableView];
NSIndexPath *hitIndex = [self.myTableView indexPathForRowAtPoint:hitPoint];
NSLog(@"%ld", (long)hitIndex.row); //This works and I can see the row which button placed
MyCustomViewCell *cell = [_myTableView dequeueReusableCellWithidentifier:@"myCell"];
//I''m tried this:
cell.button.titleLabel.text = @"111";
//and I''m tried this:
[cell.button setTitle:@"222" forState:UIControlStateNormal];
}
¿Qué estoy haciendo mal?
- (UITableViewCell *) tableView: (UITableView *) tableView cellForRowAtIndexPath (NSIndexPath *) indexPath {
MyCustomViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"myCell"];
if (!cell) {
cell=[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"myCell"];
cell.accessoryType= UITableViewCellAccessoryDisclosureIndicator;
}
cell.textLabel.text = _productNameForClearance;
cell.imageView.image = _productImageForBasket;
return cell;
}
Agregue el controlador de acción que proporciona el evento táctil al botón en la celda. Me gusta esto:
- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString* reuseIdentifier = [self cellReuseIdentifierForIndexPath:indexPath];
MyCustomCell* cell = (MyCustomCell*)[tableView dequeueReusableCellWithIdentifier:reuseIdentifier];
[cell.button addTarget:self action:@selector(cellButtonAction:forEvent:) forControlEvents:UIControlEventTouchUpInside];
// your implementation
}
Y aquí está cellButtonAction:forEvent:
implementación:
- (IBAction)cellButtonAction:(id)sender forEvent:(id)event
{
NSSet *touches = [event allTouches];
UITouch *touch = [touches anyObject];
CGPoint currentTouchPosition = [self.tableView indexPathForRowAtPoint:currentTouchPosition];
NSIndexPath* indexPath = [self.tableView indexPathForRowAtPoint:currentTouchPosition];
// your code here
MyCustomCell* cell = [self.tableView cellForRowAtIndexPath: indexPath];
[cell.button setTitle:@"222" forState:UIControlStateNormal];
}
Espero que esto ayude.
La razón por la que su código no funciona es porque este código le da una celda completamente no relacionada:
MyCustomViewCell *cell = [_myTableView dequeueReusableCellWithidentifier:@"myCell"];
Tiene la clase correcta, por lo que puede modificarla sin un error, pero no es la celda visible en su UITableView
.
Sin embargo, debería tener algún estado que no sea UI que le diga qué título mostrar: de lo contrario, si se desplaza una celda con el nuevo título fuera de la pantalla y vuelve a aparecer, se devolverá el título antiguo, lo que sería incorrecto.
Para hacer lo que está tratando de lograr correctamente, debe implementar el cambio en dos lugares: primero, el código doSomething
debe modificar el estado del modelo responsable de cambiar el título, así:
// This needs to be part of your model
NSMutableSet *rowsWithChangedTitle = ...
- (IBAction) doSomething:(id) sender {
CGPoint hitPoint = [sender convertPoint:CGPointZero toView:self.myTableView];
NSIndexPath *hitIndex = [self.myTableView indexPathForRowAtPoint:hitPoint];
NSLog(@"%ld", (long)hitIndex.row); //This works and I can see the row which button placed
[myModel.rowsWithChangedTitle addObject:@(hitIndex.row) ];
[self.myTableView reloadData];
}
Entonces, necesitaría cambiar su tableView:cellForRowAtIndexPath:
así:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
MyCustomViewCell *cell = [_myTableView dequeueReusableCellWithidentifier:@"myCell"];
...
if ([myModel.rowsWithChangedTitle containsObject:@(indexPath.row)]) {
cell.button.titleLabel.text = @"111";
[cell.button setTitle:@"222" forState:UIControlStateNormal];
}
...
}
Reemplazar línea:
MyCustomViewCell *cell = [_myTableView dequeueReusableCellWithidentifier:@"myCell"];
con:
MyCustomViewCell *cell = [_myTableView cellForRowAtIndexPath: hitIndex]
Cuando presiona el botón, el título cambia, pero cuando se desplaza y la fila con el título modificado desaparece, la celda se recicla y cuando retrocede, la celda se toma del grupo reciclado y se configura con los valores iniciales. Mi consejo es crear una matriz donde realizar un seguimiento de sus filas (títulos) modificados y en el método cellForRowAtIndexPath: debería mostrar el título modificado de esa matriz.