Memiliki UITextField dalam UITableViewCell

178

Saya mencoba untuk melakukan itu selama beberapa hari sekarang, dan setelah membaca berton-ton orang yang mencoba melakukan itu juga, saya masih belum dapat sepenuhnya bekerja UITextFielddi beberapa saya UITableViewCells, seperti dalam contoh ini:

Tangkapan layar

Entah saya memiliki formulir yang berfungsi tetapi teksnya tidak terlihat (walaupun saya mengatur warnanya menjadi biru), keyboard masuk ke lapangan ketika saya mengkliknya dan saya belum dapat mengimplementasikan acara keyboard dengan benar. Saya mencoba dengan banyak contoh dari Apple (terutama UICatalog, di mana ada kontrol yang agak mirip) tetapi masih tidak berfungsi dengan benar.

Adakah yang bisa membantu saya (dan semua orang yang berusaha mewujudkan kontrol ini) dan memposting implementasi sederhana dari UITextFielda UITableViewCell, yang berfungsi dengan baik?

Mathieu
sumber
Saya sudah berhasil. Tetapi hanya untuk beberapa bidang. Apakah Anda mengalami masalah ketika Anda memiliki beberapa bidang dalam tabel atau hanya satu?
PEZ
Saya hanya perlu itu bekerja untuk 2 bidang ... Ini tidak berfungsi sekarang, bahkan jika saya mencoba untuk satu bidang. Bisakah Anda memposting implementasi yang berfungsi? PEZ terima kasih!
Mathieu
Apakah Anda mencoba sampel EditableDetailView? Menulis pertanyaan di sini juga karena Anda belum bisa mengomentari jawaban.
PEZ
hai teman-teman dimungkinkan untuk menambahkan beberapa textfield di tableview stackoverflow.com/questions/19621732/…
Siva
2
Mengapa semua jawaban di web muncul CGRectMake(A_MAGIC_NUMBER, ANOTHER_MAGIC_NUMBER, YET_ANOTHER_HARDCODED_MAGIC_NUMBER, OH_HERES_ANOTHER_MYSTERIOUS_HARDCODED_MAGIC_NUMBER)? Dari mana angka-angka itu berasal?
jameshfisher

Jawaban:

222

Coba ini. Bekerja seperti pesona bagi saya (di perangkat iPhone). Saya menggunakan kode ini untuk layar masuk sekali. Saya mengonfigurasi tampilan tabel untuk memiliki dua bagian. Tentu saja Anda dapat menyingkirkan persyaratan bagian.

- (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;    
}

Hasilnya terlihat seperti ini:

formulir masuk

raksasa
sumber
1
Saya mencoba hal yang hampir sama persis. Namun, bidang teks hanya muncul ketika baris dipilih. Kalau tidak, tidak ditarik sama sekali. Dalam contoh di atas saya baru saja mendapatkan label, yaitu Login. Ini dengan iOS 4.2 di iPad.
David
3
Sebenarnya, pertanyaan yang lebih baik: bagaimana Anda menangani acara keyboard berikutnya / kembali?
Rob
3
@Rob: Anda bisa mendapatkan data melalui acara. Saya ambil isi dari UITextField pada acara editingDidEnd, mengaturnya seperti: [_field addTarget:self action:@selector(editingEnded:) forControlEvents:UIControlEventEditingDidEnd];.
Corey Larson
7
Anda perlu menambahkan UITextField sebagai subview dari cell.contentView dan bukan sel itu sendiri.
Mark Adams
6
Gunakan [cell addSubview:playerTextField];untuk membuatnya berfungsi dengan iOS 5.0+.
Stunner
47

Berikut adalah solusi yang terlihat bagus di bawah iOS6 / 7/8/9 .

Pembaruan 2016-06-10: ini masih berfungsi dengan iOS 9.3.3

Terima kasih atas semua dukungan Anda, ini sekarang di CocoaPods / Carthage / SPM di https://github.com/fulldecent/FDTextFieldTableViewCell

Pada dasarnya kami mengambil stok UITableViewCellStyleValue1dan pokok di UITextFieldmana detailTextLabelseharusnya. Ini memberi kami penempatan otomatis untuk semua skenario: iOS6 / 7/8/9, iPhone / iPad, Gambar / Tidak-gambar, Aksesori / Tanpa-aksesori, Potret / Lanskap, 1x / 2x / 3x.

masukkan deskripsi gambar di sini

Catatan: ini menggunakan storyboard dengan UITableViewCellStyleValue1sel tipe bernama "kata".

- (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
sumber
2
Terima kasih telah menelusuri pegunungan suara di atas untuk melihat jawaban ini!
William Entriken
1
Dengan UITableViewCellStyleRightDetailmaksud Anda UITableViewCellStyleValue1?
ma11hew28
1
Melempar 'Tidak dapat secara bersamaan memenuhi kendala' dengan dinding teks di konsol, sayangnya.
dreamzor
Juga, jika cell.detailTextLabel disetel ke tersembunyi, itu sama sekali tidak menyelaraskan sisi kanannya ('trailing').
dreamzor
Ini macet menggunakan storyboard dengan saya. Bisakah Anda menggunakan ini dengan storyboard?
Siriss
23

Inilah cara saya mencapai ini:

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];
}

Ini mungkin tampak sedikit bertele-tele, tetapi berhasil!

Jangan lupa mengatur delegasi!

pembohong
sumber
16

Coba yang ini. Ia juga dapat menangani pengguliran dan Anda dapat menggunakan kembali sel tanpa harus repot-repot menghapus subview yang Anda tambahkan sebelumnya.

- (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
sumber
Apakah cuplikan ini tidak memiliki [rilis inputTexts] di suatu tempat? Mungkin dalam metode viewDidUnload, jika tidak ada kebocoran memori.
Tim Potter
Posting lama tapi ... Saya tidak bisa membuat font kotak teks lebih kecil atau lebih besar. Apa itu mungkin?
Schultz9999
1
Adakah yang bisa memberikan solusi cuplikan Swift?
Kaptain
14

Ini seharusnya tidak sulit. Saat membuat sel untuk tabel Anda, tambahkan objek UITextField ke tampilan konten sel

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

Tetapkan delegasi dari UITextField sebagai diri sendiri (yaitu viewcontroller Anda) Berikan tag ke bidang teks sehingga Anda dapat mengidentifikasi bidang teks mana yang diedit dalam metode delegasi Anda. Keyboard akan muncul ketika pengguna mengetuk bidang teks. Saya membuatnya bekerja seperti ini. Semoga ini bisa membantu.

hilangInTransit
sumber
Saya kebetulan menyukai solusi ini. Jika Anda mengatur bidang teks Anda sebelumnya dengan CGRectZerosebagai bingkai, pastikan Anda mengatur bingkai bidang teks Anda sebelum Anda menambahkannya ke hierarki tampilan. Mendapatkan frameproperti tampilan konten sel sangat membantu untuk tugas seperti itu.
Ben Kreeger
11

Detail

  • Xcode 10.2 (10E125), Swift 5

Kode Sampel Lengkap

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)\"")
        }
    }
}

Hasil

masukkan deskripsi gambar di sini

Bodnarchuk dengan mudah
sumber
9

Saya telah menghindari ini dengan memanggil metode untuk menjalankan [cell.contentView bringSubviewToFront:textField]setiap kali sel saya muncul, tetapi kemudian saya menemukan teknik yang relatif sederhana ini:

cell.accessoryView = textField;

Tampaknya tidak memiliki masalah background-overpasting yang sama, dan itu menyelaraskan dirinya sendiri (agak). Juga, textLabel otomatis terpotong untuk menghindari meluap ke (atau di bawah) itu, yang berguna.

Ben Mosher
sumber
Aku mengambilnya kembali .. Aku tidak suka. = (
Henley Chiu
10
Hisoka - apa yang terjadi?
Ben Mosher
4

Saya mengalami masalah yang sama. Tampaknya pengaturan cell.textlabel.textproperti membawa UILabel ke depan contentView sel. Tambahkan textView setelah pengaturan textLabel.text, atau (jika itu tidak mungkin) panggil ini:

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

Saya benar-benar kesulitan dengan tugas ini di iPad, dengan bidang teks yang muncul tidak terlihat di UITableView, dan seluruh baris berubah menjadi biru saat fokus.

Apa yang berhasil bagi saya pada akhirnya adalah teknik yang dijelaskan di bawah "Teknik untuk Konten Baris Statis" dalam Panduan Pemrograman Tabel Tampilan Apple . Saya meletakkan label dan textField dalam UITableViewCell di NIB untuk tampilan, dan menarik sel itu keluar melalui outlet masuk cellForRowAtIndexPath:. Kode yang dihasilkan jauh lebih rapi daripada UICatalog.

Bryan
sumber
1

Begini caranya, saya percaya cara yang benar. Ini berfungsi pada Ipad dan Iphone saat saya mengujinya. Kita harus membuat customCell kita sendiri dengan mengklasifikasikan uitableviewcell:

mulai di interfaceBuilder ... buat UIViewcontroller baru, sebut saja customCell (sukarelawan untuk xib saat Anda di sana) Pastikan customCell adalah subkelas uitableviewcell

hapus semua tampilan sekarang dan buat satu tampilan membuatnya seukuran sel individual. buat tampilan kustom subclass itu. sekarang buat dua tampilan lain (duplikat yang pertama).
Pergi ke inspektur koneksi Anda dan temukan 2 IBOutlet yang dapat Anda sambungkan ke tampilan ini sekarang.

-backgroundView -SelectedBackground

hubungkan ini ke dua tampilan terakhir yang baru saja Anda tiru dan jangan khawatir tentang mereka. tampilan pertama yang meluas customCell, letakkan label dan uitextfield di dalamnya. masuk ke customCell.h dan hubungkan label dan bidang teks Anda. Atur ketinggian tampilan ini untuk mengatakan 75 (tinggi setiap sel) semua selesai.

Di file customCell.m Anda, pastikan konstruktornya terlihat seperti ini:

- (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;
}

Sekarang buat UITableViewcontroller dan dalam metode ini gunakan kelas customCell seperti ini:

- (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
sumber
0

Berikut adalah sub-kelas drop-in UITableViewCellyang menggantikan detailTextLabel dengan yang dapat diedit UITextField(atau, dalam kasus UITableViewCellStyleDefault, menggantikan textLabel ). Ini memiliki manfaat yang memungkinkan Anda untuk menggunakan kembali semua UITableViewCellStyles, aksesoriViews, dll., Sekarang detailnya dapat diedit!

@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

Mudah digunakan - cukup buat sel Anda seperti sebelumnya, tetapi sekarang gunakan cell.textField alih-alih cell.detailTextLabel (atau cell.textLabel jika UITableViewCellStyleDefault). misalnya

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
...

Terinspirasi oleh, dan diperbaiki, jawaban FD

tiritea
sumber
0

Untuk peristiwa berikutnya / kembali pada beberapa UITextfield di dalam UITableViewCell dalam metode ini saya telah mengambil UITextField di storyboard.

@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];
    }

}  

Untuk mengambil teks dari bidang teks-

- (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
sumber