Tener un UITextField en un UITableViewCell

178

Estoy tratando de hacer eso durante un par de días, y después de leer toneladas de mensajes de personas que intentan hacer eso también, todavía no puedo tener un trabajo completo UITextFielden algunos de mis UITableViewCells, al igual que en este ejemplo:

Captura de pantalla

O tengo el formulario funcionando pero el texto no es visible (aunque configuré su color en azul), el teclado aparece en el campo cuando hago clic en él y no he podido implementar correctamente los eventos del teclado. Intenté con un montón de ejemplos de Apple (principalmente UICatalog, donde hay un control un poco similar) pero todavía no funciona correctamente.

¿Alguien puede ayudarme (y todas las personas que intentan realizar este control) y publicar una implementación simple de a UITextFielden a UITableViewCell, que funciona bien?

Mathieu
fuente
Lo he tenido funcionando. Pero solo por unos pocos campos. ¿Se encuentra con problemas cuando tiene varios campos en la tabla o solo uno?
PEZ
Solo necesito que funcione para 2 campos ... No está funcionando en este momento, incluso si intento para un campo. ¿Puedes publicar tu implementación que está funcionando? Gracias PEZ!
Mathieu
¿Probaste la muestra EditableDetailView? Escribir la pregunta aquí también, ya que todavía no puedes comentar las respuestas.
PEZ
hola amigos, es posible agregar múltiples campos de texto en tableview stackoverflow.com/questions/19621732/…
Siva
2
¿Por qué todas las respuestas en la web se reducen a CGRectMake(A_MAGIC_NUMBER, ANOTHER_MAGIC_NUMBER, YET_ANOTHER_HARDCODED_MAGIC_NUMBER, OH_HERES_ANOTHER_MYSTERIOUS_HARDCODED_MAGIC_NUMBER)? ¿De dónde vienen esos números?
jameshfisher

Respuestas:

222

Probar esto. Funciona como un encanto para mí (en dispositivos iPhone). Usé este código para una pantalla de inicio de sesión una vez. Configuré la vista de tabla para tener dos secciones. Por supuesto, puede deshacerse de la sección condicionales.

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:kCellIdentifier];
if (cell == nil) {
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault 
                                   reuseIdentifier:kCellIdentifier] autorelease];
    cell.accessoryType = UITableViewCellAccessoryNone;

    if ([indexPath section] == 0) {
        UITextField *playerTextField = [[UITextField alloc] initWithFrame:CGRectMake(110, 10, 185, 30)];
        playerTextField.adjustsFontSizeToFitWidth = YES;
        playerTextField.textColor = [UIColor blackColor];
        if ([indexPath row] == 0) {
            playerTextField.placeholder = @"[email protected]";
            playerTextField.keyboardType = UIKeyboardTypeEmailAddress;
            playerTextField.returnKeyType = UIReturnKeyNext;
        }
        else {
            playerTextField.placeholder = @"Required";
            playerTextField.keyboardType = UIKeyboardTypeDefault;
            playerTextField.returnKeyType = UIReturnKeyDone;
            playerTextField.secureTextEntry = YES;
        }       
        playerTextField.backgroundColor = [UIColor whiteColor];
        playerTextField.autocorrectionType = UITextAutocorrectionTypeNo; // no auto correction support
        playerTextField.autocapitalizationType = UITextAutocapitalizationTypeNone; // no auto capitalization support
        playerTextField.textAlignment = UITextAlignmentLeft;
        playerTextField.tag = 0;
        //playerTextField.delegate = self;

        playerTextField.clearButtonMode = UITextFieldViewModeNever; // no clear 'x' button to the right
        [playerTextField setEnabled: YES];

        [cell.contentView addSubview:playerTextField];

        [playerTextField release];
    }
}
if ([indexPath section] == 0) { // Email & Password Section
    if ([indexPath row] == 0) { // Email
        cell.textLabel.text = @"Email";
    }
    else {
        cell.textLabel.text = @"Password";
    }
}
else { // Login button section
    cell.textLabel.text = @"Log in";
}
return cell;    
}

El resultado se ve así:

formulario de inicio de sesión

leviatán
fuente
1
Estoy intentando casi exactamente lo mismo. Sin embargo, el campo de texto solo aparece cuando se selecciona la fila. De lo contrario, no se dibuja en absoluto. En el ejemplo anterior, acabo de obtener la etiqueta, es decir, Iniciar sesión. Esto es con iOS 4.2 en iPad.
David
3
En realidad, una pregunta aún mejor: ¿cómo manejas el evento de teclado siguiente / retorno?
Rob
3
@Rob: puede obtener los datos a través de eventos. Agarro el contenido de la UITextField en el caso editingDidEnd, lo instalan de esta manera: [_field addTarget:self action:@selector(editingEnded:) forControlEvents:UIControlEventEditingDidEnd];.
Corey Larson
77
Debe agregar UITextField como una subvista de cell.contentView y no la celda en sí.
Mark Adams
66
Úselo [cell addSubview:playerTextField];para que funcione con iOS 5.0+.
Aturdidor
47

Aquí hay una solución que se ve bien en iOS6 / 7/8/9 .

Actualización 2016-06-10: esto todavía funciona con iOS 9.3.3

Gracias por todo su apoyo, ahora está en CocoaPods / Carthage / SPM en https://github.com/fulldecent/FDTextFieldTableViewCell

Básicamente hacemos el inventario UITableViewCellStyleValue1y grapamos un lugar UITextFielddonde detailTextLabelse supone que debe estar. Esto nos brinda una ubicación automática para todos los escenarios: iOS6 / 7/8/9, iPhone / iPad, Imagen / Sin imagen, Accesorio / Sin accesorio, Retrato / Paisaje, 1x / 2x / 3x.

ingrese la descripción de la imagen aquí

Nota: esto está usando el guión gráfico con una UITableViewCellStyleValue1celda de tipo llamada "palabra".

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    cell = [tableView dequeueReusableCellWithIdentifier:@"word"];
    cell.detailTextLabel.hidden = YES;
    [[cell viewWithTag:3] removeFromSuperview];
    textField = [[UITextField alloc] init];
    textField.tag = 3;
    textField.translatesAutoresizingMaskIntoConstraints = NO;
    [cell.contentView addSubview:textField];
    [cell addConstraint:[NSLayoutConstraint constraintWithItem:textField attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:cell.textLabel attribute:NSLayoutAttributeTrailing multiplier:1 constant:8]];
    [cell addConstraint:[NSLayoutConstraint constraintWithItem:textField attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:cell.contentView attribute:NSLayoutAttributeTop multiplier:1 constant:8]];
    [cell addConstraint:[NSLayoutConstraint constraintWithItem:textField attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:cell.contentView attribute:NSLayoutAttributeBottom multiplier:1 constant:-8]];
    [cell addConstraint:[NSLayoutConstraint constraintWithItem:textField attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:cell.detailTextLabel attribute:NSLayoutAttributeTrailing multiplier:1 constant:0]];
    textField.textAlignment = NSTextAlignmentRight;
    textField.delegate = self;
    return cell;
}
William Entriken
fuente
2
¡Gracias por desplazarse por las montañas de votos de arriba para ver esta respuesta!
William Entriken
1
¿A UITableViewCellStyleRightDetailqué te refieres UITableViewCellStyleValue1?
ma11hew28
1
Lanza "No es posible satisfacer simultáneamente las restricciones" con el muro de texto en la consola, desafortunadamente.
dreamzor
Además, si cell.detailTextLabel está configurado como oculto, no se alineará en absoluto con su lado derecho ('final').
dreamzor
Esto se bloquea al usar el guión gráfico conmigo. ¿Puedes usar esto con storyboard?
Siriss
23

Así es como lo he logrado:

TextFormCell.h

#import <UIKit/UIKit.h>

#define CellTextFieldWidth 90.0
#define MarginBetweenControls 20.0

@interface TextFormCell : UITableViewCell {
 UITextField *textField;
}

@property (nonatomic, retain) UITextField *textField;

@end

TextFormCell.m

#import "TextFormCell.h"

@implementation TextFormCell

@synthesize textField;

- (id)initWithReuseIdentifier:(NSString *)reuseIdentifier {
    if (self = [super initWithReuseIdentifier:reuseIdentifier]) {
  // Adding the text field
  textField = [[UITextField alloc] initWithFrame:CGRectZero];
  textField.clearsOnBeginEditing = NO;
  textField.textAlignment = UITextAlignmentRight;
  textField.returnKeyType = UIReturnKeyDone;
  [self.contentView addSubview:textField];
    }
    return self;
}

- (void)dealloc {
 [textField release];
    [super dealloc];
}

#pragma mark -
#pragma mark Laying out subviews

- (void)layoutSubviews {
 CGRect rect = CGRectMake(self.contentView.bounds.size.width - 5.0, 
        12.0, 
        -CellTextFieldWidth, 
        25.0);
 [textField setFrame:rect];
 CGRect rect2 = CGRectMake(MarginBetweenControls,
       12.0,
         self.contentView.bounds.size.width - CellTextFieldWidth - MarginBetweenControls,
         25.0);
 UILabel *theTextLabel = (UILabel *)[self textLabel];
 [theTextLabel setFrame:rect2];
}

Puede parecer un poco detallado, ¡pero funciona!

¡No olvide configurar el delegado!

charlax
fuente
16

Prueba este. También puede manejar el desplazamiento y puede reutilizar las celdas sin la molestia de eliminar las subvistas que agregó anteriormente.

- (NSInteger)tableView:(UITableView *)table numberOfRowsInSection:(NSInteger)section{
    return 10;
}   

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

    cell.textLabel.text = [[NSArray arrayWithObjects:@"First",@"Second",@"Third",@"Forth",@"Fifth",@"Sixth",@"Seventh",@"Eighth",@"Nineth",@"Tenth",nil] 
                           objectAtIndex:indexPath.row];

    if (indexPath.row % 2) {
        UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(0, 0, 200, 21)];
        textField.placeholder = @"Enter Text";
        textField.text = [inputTexts objectAtIndex:indexPath.row/2];
        textField.tag = indexPath.row/2;
        textField.delegate = self;
        cell.accessoryView = textField;
        [textField release];
    } else
        cell.accessoryView = nil;

    cell.selectionStyle = UITableViewCellSelectionStyleNone;
    return cell;        
}

- (BOOL)textFieldShouldEndEditing:(UITextField *)textField {
    [inputTexts replaceObjectAtIndex:textField.tag withObject:textField.text];
    return YES;
}

- (void)viewDidLoad {
    inputTexts = [[NSMutableArray alloc] initWithObjects:@"",@"",@"",@"",@"",nil];
    [super viewDidLoad];
}
Ali
fuente
¿Le falta a este fragmento una [versión de inputTexts] en alguna parte? Posiblemente en el método viewDidUnload, de lo contrario hay una pérdida de memoria.
Tim Potter
Publicación anterior pero ... No puedo hacer que la fuente del cuadro de texto sea más pequeña o más grande. ¿Es posible?
Schultz9999
1
¿Alguien puede proporcionar una solución de fragmento Swift?
Kaptain
14

Esto no debería ser difícil. Al crear una celda para su tabla, agregue un objeto UITextField a la vista de contenido de la celda

UITextField *txtField = [[UITextField alloc] initWithFrame....]
...
[cell.contentView addSubview:txtField]

Establezca el delegado de UITextField como self (es decir, su controlador de vista). Dé una etiqueta al campo de texto para que pueda identificar qué campo de texto se editó en sus métodos de delegado. El teclado debería aparecer cuando el usuario toca el campo de texto. Lo tengo funcionando así. Espero eso ayude.

perdido en el transito
fuente
Me gusta esta solución. Si configura su campo de texto con anticipación CGRectZerocomo un marco, asegúrese de configurar el marco de su campo de texto antes de agregarlo a la jerarquía de vistas. Obtener la framepropiedad de la vista de contenido de la celda es especialmente útil para tal tarea.
Ben Kreeger
11

Detalles

  • Xcode 10.2 (10E125), Swift 5

Código de muestra completo

TextFieldInTableViewCell

import UIKit

protocol TextFieldInTableViewCellDelegate: class {
    func textField(editingDidBeginIn cell:TextFieldInTableViewCell)
    func textField(editingChangedInTextField newText: String, in cell: TextFieldInTableViewCell)
}

class TextFieldInTableViewCell: UITableViewCell {

    private(set) weak var textField: UITextField?
    private(set) weak var descriptionLabel: UILabel?

    weak var delegate: TextFieldInTableViewCellDelegate?

    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        setupSubviews()
    }

    private func setupSubviews() {
        let stackView = UIStackView()
        stackView.distribution = .fill
        stackView.alignment = .leading
        stackView.spacing = 8
        contentView.addSubview(stackView)
        stackView.translatesAutoresizingMaskIntoConstraints = false
        stackView.topAnchor.constraint(equalTo: topAnchor, constant: 6).isActive = true
        stackView.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -6).isActive = true
        stackView.leftAnchor.constraint(equalTo: leftAnchor, constant: 16).isActive = true
        stackView.rightAnchor.constraint(equalTo: rightAnchor, constant: -16).isActive = true

        let label = UILabel()
        label.text = "Label"
        stackView.addArrangedSubview(label)
        descriptionLabel = label

        let textField = UITextField()
        textField.textAlignment = .left
        textField.placeholder = "enter text"
        textField.setContentHuggingPriority(.fittingSizeLevel, for: .horizontal)
        stackView.addArrangedSubview(textField)
        textField.addTarget(self, action: #selector(textFieldValueChanged(_:)), for: .editingChanged)
        textField.addTarget(self, action: #selector(editingDidBegin), for: .editingDidBegin)
        self.textField = textField

        stackView.layoutSubviews()
        selectionStyle = .none

        let gesture = UITapGestureRecognizer(target: self, action: #selector(didSelectCell))
        addGestureRecognizer(gesture)
    }

    required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) }
}

extension TextFieldInTableViewCell {
    @objc func didSelectCell() { textField?.becomeFirstResponder() }
    @objc func editingDidBegin() { delegate?.textField(editingDidBeginIn: self) }
    @objc func textFieldValueChanged(_ sender: UITextField) {
        if let text = sender.text { delegate?.textField(editingChangedInTextField: text, in: self) }
    }
}

ViewController

import UIKit

class ViewController: UIViewController {

    private weak var tableView: UITableView?
    override func viewDidLoad() {
        super.viewDidLoad()
        setupTableView()
    }
}

extension ViewController {

    func setupTableView() {

        let tableView = UITableView(frame: .zero)
        tableView.register(TextFieldInTableViewCell.self, forCellReuseIdentifier: "TextFieldInTableViewCell")
        view.addSubview(tableView)
        tableView.translatesAutoresizingMaskIntoConstraints = false
        tableView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
        tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
        tableView.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true
        tableView.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true
        tableView.rowHeight = UITableView.automaticDimension
        tableView.estimatedRowHeight = UITableView.automaticDimension
        tableView.tableFooterView = UIView()
        self.tableView = tableView
        tableView.dataSource = self

        let gesture = UITapGestureRecognizer(target: tableView, action: #selector(UITextView.endEditing(_:)))
        tableView.addGestureRecognizer(gesture)
    }
}

extension ViewController: UITableViewDataSource {

    func numberOfSections(in tableView: UITableView) -> Int { return 1 }
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return 2 }
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "TextFieldInTableViewCell") as! TextFieldInTableViewCell
        cell.delegate = self
        return cell
    }
}

extension ViewController: TextFieldInTableViewCellDelegate {

    func textField(editingDidBeginIn cell: TextFieldInTableViewCell) {
        if let indexPath = tableView?.indexPath(for: cell) {
            print("textfield selected in cell at \(indexPath)")
        }
    }

    func textField(editingChangedInTextField newText: String, in cell: TextFieldInTableViewCell) {
        if let indexPath = tableView?.indexPath(for: cell) {
            print("updated text in textfield in cell as \(indexPath), value = \"\(newText)\"")
        }
    }
}

Resultado

ingrese la descripción de la imagen aquí

Vasily Bodnarchuk
fuente
9

Había estado evitando esto llamando a un método para que se ejecutara [cell.contentView bringSubviewToFront:textField]cada vez que aparecían mis células, pero luego descubrí esta técnica relativamente simple:

cell.accessoryView = textField;

No parece tener el mismo problema de traspaso de fondo, y se alinea por sí solo (algo). Además, textLabel se trunca automáticamente para evitar desbordarse (o debajo), lo cual es útil.

Ben Mosher
fuente
Retiro eso ... No me gusta. = (
Henley Chiu
10
Hisoka, ¿qué pasó?
Ben Mosher
4

Tuve el mismo problema. Parece que establecer la cell.textlabel.textpropiedad lleva el UILabel al frente de contentView de la celda. Agregue textView después de la configuración textLabel.text, o (si eso no es posible) llame a esto:

[cell.contentView bringSubviewToFront:textField]
Arie Pieter Cammeraat
fuente
2

Realmente luché con esta tarea en el iPad, con campos de texto que se muestran invisibles en UITableView, y toda la fila se vuelve azul cuando se enfoca.

Lo que funcionó para mí al final fue la técnica descrita en "La técnica para el contenido de filas estáticas" en la Guía de programación de vista de tabla de Apple . Puse la etiqueta y el campo de texto en un UITableViewCell en el NIB para la vista, y extraigo esa celda a través de una salida cellForRowAtIndexPath:. El código resultante es mucho más ordenado que UICatalog.

Bryan
fuente
1

Así es como se hace, creo que la forma correcta. Funciona en Ipad y Iphone cuando lo probé. Tenemos que crear nuestras propias CustomCells clasificando una uitableviewcell:

comience en interfaceBuilder ... cree un nuevo controlador UIView, llámelo customCell (voluntario para un xib mientras esté allí) Asegúrese de que customCell sea una subclase de uitableviewcell

borre todas las vistas ahora y cree una vista para que sea del tamaño de una celda individual. haga que esa vista sea de la subclase customcell. ahora cree otras dos vistas (duplique la primera).
Vaya a su inspector de conexiones y encuentre 2 IBOutlets que puede conectar a estas vistas ahora.

-backgroundView -SelectedBackground

conéctelos a las dos últimas vistas que acaba de duplicar y no se preocupe por ellas. la primera vista que extiende customCell, coloca tu etiqueta y uitextfield dentro de ella. entró en customCell.h y conectó su etiqueta y campo de texto. Establezca la altura de esta vista para decir 75 (altura de cada celda) todo listo.

En su archivo customCell.m, asegúrese de que el constructor se vea así:

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
    // Initialization code
    NSArray *nibArray = [[NSBundle mainBundle] loadNibNamed:@"CustomCell"       owner:self options:nil]; 
    self = [nibArray objectAtIndex:0];
}
return self;
}

Ahora cree un UITableViewcontroller y en este método use la clase customCell de esta manera:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
// lets use our customCell which has a label and textfield already installed for us

customCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
    //cell = [[[customCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];


    NSArray *topLevelsObjects = [[NSBundle mainBundle] loadNibNamed:@"NewUserCustomCell" owner:nil options:nil];
    for (id currentObject in topLevelsObjects){
        if ([currentObject  isKindOfClass:[UITableViewCell class]]){
            cell = (customCell *) currentObject;
            break;
        }
    }

    NSUInteger row = [indexPath row];

switch (row) {
    case 0:
    {

        cell.titleLabel.text = @"First Name"; //label we made (uitextfield also available now)

        break;
    }


        }
return cell;

}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{

return 75.0;
}
j2emanue
fuente
0

Aquí hay una subclase para la UITableViewCellcual reemplaza detailTextLabel con un editable UITextField(o, en el caso de UITableViewCellStyleDefault, reemplaza textLabel ). Esto tiene la ventaja de que le permite reutilizar todos los estilos UITableViewCellStyles, accesoriosViews, etc. conocidos, ¡justo ahora el detalle es editable!

@interface GSBEditableTableViewCell : UITableViewCell <UITextFieldDelegate>
@property UITextField *textField;
@end

@interface GSBEditableTableViewCell ()
@property UILabel *replace;
@end

@implementation GSBEditableTableViewCell

- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self) {
        _replace = (style == UITableViewCellStyleDefault)? self.textLabel : self.detailTextLabel;
        _replace.hidden = YES;

        // Impersonate UILabel with an identical UITextField
        _textField = UITextField.new;
        [self.contentView addSubview:_textField];
        _textField.translatesAutoresizingMaskIntoConstraints = NO;
        [_textField.leftAnchor constraintEqualToAnchor:_replace.leftAnchor].active = YES;
        [_textField.rightAnchor constraintEqualToAnchor:_replace.rightAnchor].active = YES;
        [_textField.topAnchor constraintEqualToAnchor:_replace.topAnchor].active = YES;
        [_textField.bottomAnchor constraintEqualToAnchor:_replace.bottomAnchor].active = YES;
        _textField.font = _replace.font;
        _textField.textColor = _replace.textColor;
        _textField.textAlignment = _replace.textAlignment;

        // Dont want to intercept UITextFieldDelegate, so use UITextFieldTextDidChangeNotification instead
        [NSNotificationCenter.defaultCenter addObserver:self
                                           selector:@selector(textDidChange:)
                                               name:UITextFieldTextDidChangeNotification
                                             object:_textField];

        // Also need KVO because UITextFieldTextDidChangeNotification not fired when change programmatically
        [_textField addObserver:self forKeyPath:@"text" options:0 context:nil];
    }
    return self;
}

- (void)textDidChange:(NSNotification*)notification
{
    // Update (hidden) UILabel to ensure correct layout
    if (_textField.text.length) {
        _replace.text = _textField.text;
    } else if (_textField.placeholder.length) {
        _replace.text = _textField.placeholder;
    } else {
        _replace.text = @" "; // otherwise UILabel removed from cell (!?)
    }
    [self setNeedsLayout];
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    if ((object == _textField) && [keyPath isEqualToString:@"text"]) [self textDidChange:nil];
}

- (void)dealloc
{
    [_textField removeObserver:self forKeyPath:@"text"];
}

@end

Fácil de usar: simplemente cree su celda como antes, pero ahora use cell.textField en lugar de cell.detailTextLabel (o cell.textLabel en el caso de UITableViewCellStyleDefault). p.ej

GSBEditableTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"];
if (!cell) cell = [GSBEditableTableViewCell.alloc initWithStyle:UITableViewCellStyleValue2 reuseIdentifier:@"Cell"];

cell.textLabel.text = @"Name";
cell.textField.text = _editablename;
cell.textField.delegate = self; // to pickup edits
...

Inspirado y mejorado por la respuesta de FD

tiritea
fuente
0

Para los eventos siguientes / de retorno en múltiples UITextfield dentro de UITableViewCell en este método, tomé UITextField en el guión gráfico.

@interface MyViewController () {
    NSInteger currentTxtRow;
}
@end
@property (strong, nonatomic) NSIndexPath   *currentIndex;//Current Selected Row

@implementation MyViewController


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"CELL" forIndexPath:indexPath];
        cell.selectionStyle = UITableViewCellSelectionStyleNone;

        UITextField *txtDetails = (UITextField *)[cell.contentView viewWithTag:100];
        txtDetails.delegate = self;

        txtDetails.placeholder = self.arrReciversDetails[indexPath.row];
        return cell;
}


#pragma mark - UITextFieldDelegate
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField {

    CGPoint point = [textField convertPoint:CGPointZero toView:self.tableView];
    self.currentIndex = [self.tableView indexPathForRowAtPoint:point];//Get Current UITableView row
    currentTxtRow = self.currentIndex.row;
    return YES;
}


- (BOOL)textFieldShouldReturn:(UITextField *)textField {
    currentTxtRow += 1;
    self.currentIndex = [NSIndexPath indexPathForRow:currentTxtRow inSection:0];

    UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:self.currentIndex];
    UITextField *currentTxtfield = (UITextField *)[cell.contentView viewWithTag:100];
    if (currentTxtRow < 3) {//Currently I have 3 Cells each cell have 1 UITextfield
        [currentTxtfield becomeFirstResponder];
    } else {
        [self.view endEditing:YES];
        [currentTxtfield resignFirstResponder];
    }

}  

Para tomar el texto del campo de texto

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
      switch (self.currentIndex.row) {

            case 0:
                NSLog(@"%@",[NSString stringWithFormat:@"%@%@",textField.text,string]);//Take current word and previous text from textfield
                break;

            case 1:
                 NSLog(@"%@",[NSString stringWithFormat:@"%@%@",textField.text,string]);//Take current word and previous text from textfield
                break;

            case 2:
                 NSLog(@"%@",[NSString stringWithFormat:@"%@%@",textField.text,string]);//Take current word and previous text from textfield
                break;

            default:
                break;
        }
}
Mohammed Hussain
fuente