Having a UITextField in a UITableViewCell

162,795

Solution 1

Try this out. Works like a charm for me (on iPhone devices). I used this code for a login screen once. I configured the table view to have two sections. You can of course get rid of the section conditionals.

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

Result looks like this:

login form

Solution 2

Here is a solution that looks good under iOS6/7/8/9.

Update 2016-06-10: this still works with iOS 9.3.3

Thanks for all your support, this is now on CocoaPods/Carthage/SPM at https://github.com/fulldecent/FDTextFieldTableViewCell

Basically we take the stock UITableViewCellStyleValue1 and staple a UITextField where the detailTextLabel is supposed to be. This gives us automatic placement for all scenarios: iOS6/7/8/9, iPhone/iPad, Image/No-image, Accessory/No-accessory, Portrait/Landscape, 1x/2x/3x.

enter image description here

Note: this is using storyboard with a UITableViewCellStyleValue1 type cell named "word".

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

Solution 3

Here is how I have achieved this:

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

It may seems a bit verbose, but it works!

Don't forget to set the delegate!

Solution 4

Try this one. It can handle scrolling as well and you can reuse the cells without the hassle of removing subviews you added before.

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

Solution 5

This should not be difficult. When creating a cell for your table, add a UITextField object to the cell's content view

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

Set the delegate of the UITextField as self (ie your viewcontroller) Give a tag to the text field so you can identify which textfield was edited in your delegate methods. The keyboard should pop up when the user taps the text field. I got it working like this. Hope it helps.

Share:
162,795

Related videos on Youtube

Mathieu
Author by

Mathieu

Updated on May 10, 2020

Comments

  • Mathieu
    Mathieu almost 4 years

    I'm trying to do that for a couple of days now, and after reading tons of messages of people trying to do that too, I'm still unable to have a fully working UITextField in some of my UITableViewCells, just like in this example:

    Screenshot

    Either I have the form working but the text is not visible (although I set its color to blue), the keyboard goes on the field when I click on it and I haven't been able to correctly implement the keyboard events. I tried with a bunch of examples from Apple (mainly UICatalog, where there is a kinda similar control) but it's still not working correctly.

    Can somebody help me (and all the people trying to realize this control) and post a simple implementation of a UITextField in a UITableViewCell, that works fine?

    • PEZ
      PEZ over 15 years
      I've had it working. But only for a few fields. Are you running into problems when you have several fields in the table or just one?
    • Mathieu
      Mathieu over 15 years
      I just need it working for 2 fields... It's not working right now, even if I try for one field. Can you post your implementation that is working? Thank you PEZ!
    • PEZ
      PEZ over 15 years
      Did you try the EditableDetailView sample? Writing the question here too since you can't comment on answers yet.
    • Siva
      Siva over 10 years
      hi friends it's possible to add multiple textfield in tableview stackoverflow.com/questions/19621732/…
    • William Entriken
      William Entriken about 10 years
      Hi Mathieu, just wanted to follow up and ask if the answer below worked for you
    • jameshfisher
      jameshfisher over 9 years
      Why do all the answers on the web boil down to CGRectMake(A_MAGIC_NUMBER, ANOTHER_MAGIC_NUMBER, YET_ANOTHER_HARDCODED_MAGIC_NUMBER, OH_HERES_ANOTHER_MYSTERIOUS_HARDCODED_MAGIC_NUMBER)? Where do those numbers come from?
    • thiagowfx
      thiagowfx about 8 years
      Is it possible to do this just with interface builder?
  • David
    David over 13 years
    I'm trying almost the exact same thing. However, the text field only shows up when the row is selected. Otherwise is isn't drawn at all. In the above example I just get the label, ie Login. This is with iOS 4.2 on iPad.
  • leviathan
    leviathan over 13 years
    @David: Haven't tested this code on iPad yet. Updated the description to make it clear that this works on iPhone. Do you have a solution for iPad?
  • Tim Potter
    Tim Potter over 13 years
    Is this snippet missing a [inputTexts release] somewhere? Possibly in the viewDidUnload method, otherwise there is a memory leak.
  • K.Honda
    K.Honda almost 13 years
    I'm having this problem too. How can I implement this code into a new .h .m file?
  • Rob
    Rob almost 13 years
    How would you access the information in the cells after wards?
  • Rob
    Rob almost 13 years
    Actually, an even better question: how do you handle the next/ return keyboard event?
  • Corey Larson
    Corey Larson almost 13 years
    @Rob: You can get at the data through events. I grab the contents of the UITextField on the editingDidEnd event, set it up like so: [_field addTarget:self action:@selector(editingEnded:) forControlEvents:UIControlEventEditingDidEnd];.
  • Henley
    Henley almost 13 years
    I take that back.. Me no like. =(
  • Agos
    Agos over 12 years
    I've copied and pasted this saving myself some precious minutes before a demo ;) Awesome!
  • Mark Adams
    Mark Adams over 12 years
    You need to add the UITextField as a subview of the cell.contentView and not the cell itself.
  • barfoon
    barfoon over 12 years
    Need to add "static NSString *kCellIdentifier = @"Cell";" to the top of the method.
  • Faser
    Faser over 12 years
    Works on iPad like a charm. Needed to set the BGColor of the textFieldto clearColor
  • Ben Kreeger
    Ben Kreeger over 11 years
    I happen to like this solution. If you setup your text field ahead of time with CGRectZero as a frame, make sure you setup your text field's frame before you add it to the view hierarchy. Getting the cell's content view's frame property is especially helpful for such a task.
  • Stunner
    Stunner about 11 years
    Use [cell addSubview:playerTextField]; to get it to work with iOS 5.0+.
  • Sandip Patel - SM
    Sandip Patel - SM almost 11 years
    cell.textLabel.backgroundColor = [UIColor clearColor]; add this line to above code. this will resolve the issue of not showing text for text field because cell.textLabel having full width so its overcome on the text field
  • Schultz9999
    Schultz9999 over 10 years
    Old post but... I can't make font of the text box smaller or bigger. Is it possible?
  • Giorgio
    Giorgio over 10 years
    This doesn't work if the cells have to be reused. It may happen that the password cell can be shown in Login cell and vice versa.
  • Siva
    Siva over 10 years
    hi friends it's possible to add multiple textfield in tableview stackoverflow.com/questions/19621732/…
  • Esqarrouth
    Esqarrouth about 10 years
    I am having problem with Robs question aswell, how to handle next keyboard event?
  • William Entriken
    William Entriken about 10 years
    Thanks for scrolling through the mountains of votes above to see this answer!
  • ma11hew28
    ma11hew28 about 10 years
    By UITableViewCellStyleRightDetail do you mean UITableViewCellStyleValue1?
  • dreamzor
    dreamzor over 9 years
    Throws 'Unable to simultaneously satisfy constraints' with wall of text in console, unfortunately.
  • dreamzor
    dreamzor over 9 years
    Also, if cell.detailTextLabel is set to hidden, it doesn't align its right ('trailing') side at all.
  • Siriss
    Siriss about 9 years
    This crashes using storyboard with me. Can you use this with storyboard?
  • William Entriken
    William Entriken about 9 years
    Advertisement: newer answer below works on iOS8 stackoverflow.com/a/21590846/300224
  • Reveclair
    Reveclair about 9 years
    @FullDecent Can you also show your storyboard for this table view ?
  • Reveclair
    Reveclair about 9 years
    @FullDecent Can you also provide a solution without using a Storyboard ? Thank you
  • Kaptain
    Kaptain over 8 years
    Can somebody provide an Swift snippet solution?
  • Joe
    Joe over 8 years
    I found that the textfield text was not right aligned in the cell unless you add text to the detailTextLabel. Simply adding cell.detailTextLabel.Text = @"0" adjusted the textfield frame to stretch to the end of the cell.
  • William Entriken
    William Entriken almost 8 years
    Thanks everyone, this is now on CocoaPods
  • Bavafaali
    Bavafaali over 3 years
    In my case just changing cell.addsubview to cell.contentView.addSubview did it...