Tengo una celda UITableView personalizada a la que he agregado un cuadro de texto para editar, que muestra y oculta en función del modo de edición. También intenté agregar una línea vertical que se muestra al editar, y lo hace, pero tengo algunos problemas de dibujo. Acabo de agregar una marca de verificación verde a la derecha para comenzar a trabajar en los comentarios de validación de entrada, y estoy viendo problemas similares.UITableViewCell personalizado vuelve a dibujar problemas
Aquí está el código para la celda y parte de mi cellForRowAtIndexPath.
#import <UIKit/UIKit.h>
@interface EditableCellStyle2 : UITableViewCell {
CGRect editRect;
UITextField *editField;
UIView *lineView;
}
@property (nonatomic, readonly, retain) UITextField *editField;
@property (nonatomic, readonly, retain) UIView *lineView;
@end
#import "EditableCellStyle2.h"
@implementation EditableCellStyle2
@synthesize editField;
@synthesize lineView;
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
// Initialization code.
editRect = CGRectMake(83, 12, self.contentView.bounds.size.width-83, 19);
editField = [[UITextField alloc] initWithFrame:editRect];
editField.font = [UIFont boldSystemFontOfSize:15];
editField.textAlignment = UITextAlignmentLeft;
editField.textColor = [UIColor blackColor];
editField.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleHeight;
[self.contentView addSubview:editField];
self.editField.enabled = NO;
self.editField.hidden = YES;
lineView = [[UIView alloc] initWithFrame:CGRectMake(80, 0, 1, self.contentView.bounds.size.height)];
self.lineView.backgroundColor = [UIColor lightGrayColor];
[self.contentView addSubview:lineView];
self.lineView.hidden = YES;
}
return self;
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
[super setSelected:selected animated:animated];
// Configure the view for the selected state.
}
-(void)layoutSubviews
{
[super layoutSubviews]; // layouts the cell as UITableViewCellStyleValue2 would normally look like
editRect = CGRectMake(83, 12, self.contentView.frame.size.width-self.detailTextLabel.frame.origin.x-10, 19);
editField.frame = editRect;
}
- (void)willTransitionToState:(UITableViewCellStateMask)state {
[super willTransitionToState:state];
if (state & UITableViewCellStateEditingMask) {
self.detailTextLabel.hidden = YES;
self.editField.enabled = YES;
self.lineView.hidden = NO;
self.editField.hidden = NO;
}
}
- (void)didTransitionToState:(UITableViewCellStateMask)state {
[super didTransitionToState:state];
if (!(state & UITableViewCellStateEditingMask)) {
self.editField.enabled = NO;
self.editField.hidden = YES;
self.lineView.hidden = YES;
self.detailTextLabel.hidden = NO;
self.editField.text = self.detailTextLabel.text;
}
}
- (void)dealloc {
[editField release];
[lineView release];
[super dealloc];
}
@end
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// handling every section by hand since this view is essentially static. Sections 0, 1, 2, and 4 use a generic editable cell.
// Section 3 uses the multiline address cell.
static NSString *CellIdentifier = @"Cell";
EditableCellStyle2 *cell = (EditableCellStyle2 *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (indexPath.section == 0 || indexPath.section == 1 || indexPath.section == 2 || indexPath.section == 4) {
if (cell == nil) {
cell = [[[EditableCellStyle2 alloc] initWithStyle:UITableViewCellStyleValue2 reuseIdentifier:CellIdentifier] autorelease];
}
}
// Configure the Odometer
if (indexPath.section == 0) {
NSArray *array = [sectionsArray objectAtIndex:indexPath.section];
NSDictionary *dictionary = [array objectAtIndex:indexPath.row];
cell.textLabel.text = @"Odometer";
cell.detailTextLabel.text = [NSString stringWithFormat:@"%@", [dictionary objectForKey:@"Odometer"]];
cell.tag = kOdometer;
cell.editField.text = cell.detailTextLabel.text;
cell.editField.placeholder = @"Odometer";
cell.editField.tag = kOdometer;
cell.editField.keyboardType = UIKeyboardTypeNumberPad;
// Create a view for the green checkmark for odometer input validation and set it as the right view.
UIImage *checkImage = [UIImage imageNamed:@"tick.png"];
UIImageView *checkImageView = [[[UIImageView alloc] initWithImage:checkImage] autorelease];
cell.editField.rightView = checkImageView;
cell.editField.rightViewMode = UITextFieldViewModeAlways;
}
return cell;
}
No hay más que eso, pero todas las células se construyen de la misma manera.
Los problemas son que, cuando se está en el modo de edición, las líneas verticales se mostrarán correctamente. Cuando salgo del modo de edición, las celdas que estaban fuera de la pantalla cuando voy al modo normal siguen teniendo la línea vertical (no se oculta). Además, ahora que he agregado el imageView para el indicador de marca de verificación, las celdas que están fuera de la pantalla al cambiar de modo obtienen la marca de verificación. (solo la sección 0 lo configura).
También he notado que si hago cell.setNeedsDisplay, la etiqueta de texto y la etiqueta de texto de detalle no se actualizarán si la fuente de datos se ha actualizado. Tengo que hacer [self.tableView reloadData] que omite cualquier animación activa.
Estoy seguro de que estos problemas están relacionados con mi uso de una celda personalizada + dequeueReusableCellWithIdentifier, pero no puedo encontrar exactamente qué.
Cualquier comentario o impulso en la dirección correcta sería apreciado.
Editar: Al no utilizar las celdas reutilizables, parece que se han resuelto los problemas anteriores. Todavía estoy abierto a comentarios sobre el código de la celda. Olvidé otro problema que puede o no estar relacionado. Una de mis celdas tiene un botón "tocar para ver la lista". Si ingreso datos en las celdas mientras estoy en modo de edición, entonces presiono ese botón para elegir información de una lista (muestra una vista de tabla modal), cuando dejo de lado la vista modal, todos los datos editados de las celdas se han revertido a su estado original. No estoy llamando datos de recarga cuando descarto el controlador de vista modal. Pensé que esto podría solucionarse al no usar células reutilizables, pero no es así.
Sí parece un problema con las células reutilizables. ¿Qué tan grande es tu tabla vista? Lo suficientemente grande como para justificar la reutilización de las células? ¿Si no los abandona y deja que la vista de tabla cree instancias individuales de sus celdas? – Rog
La vista de tabla es bastante pequeña, es una vista detallada de una entrada de datos central. Tal vez 7 células, las tapas. Tengo la extraña sensación de haber estropeado las presentaciones de mi celular en alguna parte. – Chuck
Estoy teniendo más o menos exactamente el mismo problema, por lo que agrego una recompensa en caso de que la gente lo note y lo ayude, ayudándome al mismo tiempo. Estoy bastante seguro de que es uno de esos doh! detalles, pero aún así :-) – niklassaers