2011-07-05 9 views
13

Ya casi termino de implementar un UITableViewCell con un UITextField en él. En lugar de pasar por CGRectMake y UITableViewCell.contentView he implementado de la manera más simple:UITableViewCell con UITextField perdiendo la posibilidad de seleccionar la fila UITableView?

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:@"Cell"]; 
    [cell setSelectionStyle:UITableViewCellSelectionStyleBlue]; 
    amountField = [[UITextField alloc] initWithFrame:CGRectMake(110, 10, 190, 30)]; 
    amountField.placeholder = @"Enter amount"; 
    amountField.keyboardType = UIKeyboardTypeDecimalPad; 
    amountField.textAlignment = UITextAlignmentRight; 
    amountField.clearButtonMode = UITextFieldViewModeNever; 
    [amountField setDelegate:self]; 

    [[cell textLabel] setText:@"Amount"]; 
    [cell addSubview:amountField]; 
    return cell; 
} 

Y entonces yo también implementado el método didSelectRow, renunciando el campo de texto para permitir que muestra los otros campos vistas de entrada.

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    ... 
    [amountField resignFirstResponder]; 
    ... 
} 

Esto funciona sin problemas, lo único es que hay otras filas de la tabla, cuando esos otros son seleccionados se selecciona toda la célula y se vuelve azul, mientras que el uno con mi UITextField no lo hace, me refiero al campo está seleccionado y puedo ingresar texto pero la celda no está seleccionada. Lo he probado y descubierto el problema está en la línea:

[cell addSubview:amountField]; 

Parece que esto rompe el comportamiento celular seleccionable, e incluso agregarlo a [cell contentView] no soluciona esto. ¿Me he perdido algo?

Respuesta

39

Si el campo de texto tiene userInteractionEnabled conjunto de SÍ, y que se llene toda la célula, no se puede obtener la célula para escuchar al tacto. Para que la célula responda a los toques, debe configurar el userInteractionEnabled del campo de texto en NO.

Editar: Y si usted quiere hacer el campo de texto editable, cuando se selecciona la celda, agrega el siguiente código en didSelectRowAtIndexPath: método,

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

    // get the reference to the text field 
    [textField setUserInteractionEnabled:YES]; 
    [textField becomeFirstResponder]; 
} 
+0

Si establece 'userInteractionEnabled = NO;' esto no sería hacer que el UITextField no editable? –

+0

Aparentemente no: he seguido el consejo de EmptyStack y he establecido [amountField setUserInteractionEnabled: NO]; al principio del método DidSelectRow, y luego [amountField setUserInteractionEnabled: YES] solo cuando la fila seleccionada es la que tiene el campo de texto. La selección ahora está bien, pero tengo que tocar dos veces en la fila para ingresar texto ... –

+0

@micpringle, por supuesto. No puede hacer que tanto el campo de texto como la celda respondan cuando el campo de texto llena la celda. – EmptyStack

6

Usted ha roto no cualquier cosa añadiendo una subvista, en cambio, el UITextField está capturando el toque por delante de UITableViewCell. Puede probar esto tocando fuera del UITextField pero dentro de los límites de UITableViewCell y verá que de hecho todavía selecciona como era de esperar.

Para evitar esto, podría subescribir UITextField y agregar una propiedad UITableView. Establezca la propiedad cuando crea una instancia de UITextField y agréguelo a la celda.

amountField.tableView = tableView; 

Entonces será necesario reemplazar becomeFirstResponder en la subclase, y en el método de obtener la fila de la celda con el UITextField y luego seleccionar manualmente

- (BOOL)becomeFirstResponder 
{ 
    // Get the rect of the UITextView in the UITableView's coordinate system 
    CGRect position = [self convertRect:self.frame toView:self.tableView]; 
    // Ask the UITableView for all the rows in that rect, in this case it should be 1 
    NSArray *indexPaths = [self.tableView indexPathsForRowsInRect:position]; 
    // Then manually select it 
    [self.tableView selectRowAtIndexPath:[indexPaths objectAtIndex:0] animated:YES scrollPosition:UITableViewScrollPositionNone]; 
    return YES; 
} 
+0

Tienes toda la razón, lo intenté, es verdad. Gracias. –

+0

Esto también funciona, pero requiere una gran cantidad de código adicional, mientras que fija el campo de texto userInteractionEnabled = NO como se sugiere a continuación por EmptyStack fue un par de líneas de código .... al menos hasta que encuentre algún otro problema :) Gracias para su ayuda, sin embargo, hizo el problema más claro. –

+0

¿No es esto un ciclo de retención? 'tableView' ->' visibleCells' -> 'amountField' ->' tableView' – jakenberg

1

Lo primero es que no han usado células reutilizables La codificación que proporcionó causará mucha memoria.

Lo siguiente es que puede seleccionar la fila tocando el área que no sea el campo de texto.

Una solución para sus ques es

En su textField Delegado

UITableViewCell *cell = (UITableViewCell *)[textField superView]; 
cell.selected=YES; //I think this will call the didSelectRowATIndex; 

No estoy seguro de que esto va a funcionar. Pero vale la pena intentarlo.

+0

Aparte del hecho de que esta tabla tiene 4 celdas solo porque es una buena máscara de entrada, entonces la memoria no debería ser un gran problema, pero ¿por qué dices que no he usado celdas reutilizables? Pensé que lo había hecho. Voy a probar tu solución ahora. Gracias. –

+0

Creo que entendió mal el concepto reutilizable .. Ver aquí http: //developer.apple.com/library/ios/#documentation/UserExperience/Conceptual/TableView_iPhone/TableViewCells/TableViewCells.html ... En fin 4 células está bien, pero con una fila de más de 10 le causará un problema. – iPrabu

+0

Podría haber entendido mal, por supuesto, pero ¿no deberían evitarse reutilizar las células cuando todos tienen controles diferentes en su interior?De todos modos, gracias por el enlace :) –

1

Antes que nada necesita usar reuseIdentifier para cellForRowAtIndexPath, razón por la que si no usa reuseIdentifier es: cuando se desplaza hacia arriba y hacia abajo, siempre asignará nueva celda y campos de texto nuevos así que debe poner cell == condición nula , código de forma revisada está aquí:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    static NSString *reuseIdentifier = @"Cell"; 
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:reuseIdentifier]; 
if (cell==nil) { 
    cell = [[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:reuseIdentifier] autorelease]; 

    UITextField *amountField = [[UITextField alloc] initWithFrame:CGRectMake(110, 10, 190, 30)]; 
    amountField.placeholder = @"Enter amount"; 
    amountField.keyboardType = UIKeyboardTypeDecimalPad; 
    amountField.textAlignment = UITextAlignmentRight; 
    amountField.clearButtonMode = UITextFieldViewModeNever; 
    [amountField setDelegate:self]; 
    [cell.contentView addSubview:amountField]; 
} 
[cell setSelectionStyle:UITableViewCellSelectionStyleNone]; 
[[cell textLabel] setText:@"Amount"]; 

return cell; 
} 

en el método delegado didSelect se puede hacer como esto

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    [prevField resignFirstResponder]; 
    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]; 
    UIView *view = [[cell.contentView subviews] lastObject]; 
    if([view isKindOfClass:[UITextField class]]{ 
    currentField = (UITextField*)view; 
    } 
    [currentField becomeFirstResponder]; 
    prevField = currentField; 
} 
+0

Chicos, les agradezco su esfuerzo por enseñar las mejores prácticas de Cocoa, pero traté de poner allí el único código relevante, amountField no se crea una instancia cada vez, pero solo a la vista se cargaba, se verificaba! Cell está ahí pero lo omití porque no era relevante a mi pregunta, y mi tabla no se desplaza porque son solo 4 filas. El resto de tus comentarios son muy útiles. ¡Gracias! –

1

dentro de la célula para la fila en la ruta del índice añadir esta línea que se da en negrita,

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:@"Cell"]; 
    [cell setSelectionStyle:UITableViewCellSelectionStyleBlue]; 

    amountField = [[UITextField alloc] initWithFrame:CGRectMake(110, 10, 190, 30)]; 
    amountField.placeholder = @"Enter amount"; 
    amountField.keyboardType = UIKeyboardTypeDecimalPad; 
    amountField.textAlignment = UITextAlignmentRight; 
    amountField.clearButtonMode = UITextFieldViewModeNever; 

    [amountField setDelegate:self]; 
    [[cell textLabel] setText:@"Amount"]; 

    **for (UIView *cellSubViews in cell.subviews) { 
      cellSubViews.userInteractionEnabled = NO; 
    }** 

    [cell addSubview:amountField]; 
    return cell; 
} 

probar esto, funcionará

Cuestiones relacionadas