180 votes

Avoir un UITextField dans un UITableViewCell

J'essaye de le faire depuis quelques jours maintenant, et après avoir lu des tonnes de messages de personnes essayant de le faire aussi, je ne suis toujours pas capable d'avoir un fonctionnement complet UITextField dans certains de mes UITableViewCells comme dans cet exemple :

Screenshot

Soit j'ai le formulaire qui fonctionne mais le texte n'est pas visible (bien que j'ai mis sa couleur en bleu), le clavier va sur le champ quand je clique dessus et je n'ai pas réussi à implémenter correctement les événements clavier. J'ai essayé avec un tas d'exemples d'Apple (principalement UICatalog (où il existe un contrôle similaire) mais il ne fonctionne toujours pas correctement.

Quelqu'un peut-il m'aider (ainsi que toutes les personnes qui essaient de réaliser ce contrôle) et publier une mise en œuvre simple d'un contrôle de type UITextField dans un UITableViewCell qui fonctionne bien ?

0 votes

J'ai réussi à le faire fonctionner. Mais seulement pour quelques champs. Rencontrez-vous des problèmes lorsque vous avez plusieurs champs dans la table ou un seul ?

0 votes

J'ai juste besoin que ça fonctionne pour 2 champs... Cela ne fonctionne pas pour l'instant, même si j'essaie pour un seul champ. Pouvez-vous poster votre implémentation qui fonctionne ? Merci PEZ !

0 votes

Avez-vous essayé l'échantillon EditableDetailView ? Écrivez la question ici aussi puisque vous ne pouvez pas encore commenter les réponses.

225voto

leviathan Points 5207

Essayez ceci. Cela fonctionne comme un charme pour moi (sur les appareils iPhone). J'ai utilisé ce code pour un écran de connexion une fois. J'ai configuré la vue tableau pour avoir deux sections. Vous pouvez bien sûr vous débarrasser des conditionnels de section.

- (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 = @"example@gmail.com";
            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;    
}

Le résultat ressemble à ceci :

login form

1 votes

J'essaie presque exactement la même chose. Cependant, le champ de texte ne s'affiche que lorsque la ligne est sélectionnée. Sinon, il ne s'affiche pas du tout. Dans l'exemple ci-dessus, je n'obtiens que l'étiquette, c'est-à-dire Login. Ceci avec iOS 4.2 sur iPad.

0 votes

David : Je n'ai pas encore testé ce code sur l'iPad. J'ai mis à jour la description pour qu'il soit clair que cela fonctionne sur l'iPhone. Avez-vous une solution pour l'iPad ?

0 votes

J'ai aussi ce problème. Comment puis-je implémenter ce code dans un nouveau fichier .h .m ?

47voto

Full Decent Points 4453

Voici une solution qui semble bonne sous iOS6/7/8/9 .

Mise à jour 2016-06-10 : cela fonctionne toujours avec iOS 9.3.3

Merci pour tout votre soutien, ceci est maintenant sur CocoaPods/Carthage/SPM à https://github.com/fulldecent/FDTextFieldTableViewCell

En gros, on prend les actions UITableViewCellStyleValue1 et agrafer un UITextField où le detailTextLabel est censé être. Nous obtenons ainsi un placement automatique pour tous les scénarios : iOS6/7/8/9, iPhone/iPad, Image/Non-image, Accessoire/Non-accessoire, Portrait/Paysage, 1x/2x/3x.

enter image description here

Remarque : il s'agit d'utiliser le storyboard avec un UITableViewCellStyleValue1 cellule de type nommé "mot".

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

2 votes

Merci d'avoir parcouru les montagnes de votes ci-dessus pour voir cette réponse !

1 votes

Por UITableViewCellStyleRightDetail voulez-vous dire UITableViewCellStyleValue1 ?

1 votes

Lance le message "Impossible de satisfaire simultanément les contraintes" avec un mur de texte dans la console, malheureusement.

23voto

charlax Points 3653

Voici comment j'y suis parvenu :

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

Cela peut sembler un peu verbeux, mais ça marche !

N'oubliez pas de définir le délégué !

16voto

Ali Points 338

Essayez celui-ci. Il peut également gérer le défilement et vous pouvez réutiliser les cellules sans avoir à supprimer les vues secondaires que vous avez ajoutées auparavant.

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

0 votes

Est-ce qu'il manque un [inputTexts release] quelque part dans ce snippet ? Peut-être dans la méthode viewDidUnload, sinon il y a une fuite de mémoire.

0 votes

Vieux message mais... Je n'arrive pas à rendre la police de la zone de texte plus petite ou plus grande. Est-ce possible ?

1 votes

Quelqu'un peut-il fournir une solution sous forme de snippet Swift ?

15voto

newgenapps_dev Points 23557

Cela ne devrait pas être difficile. Lorsque vous créez une cellule pour votre tableau, ajoutez un objet UITextField à la vue du contenu de la cellule.

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

Définissez le délégué de l'UITextField comme self (c'est-à-dire votre viewcontroller). Donnez une balise au champ de texte afin de pouvoir identifier quel champ de texte a été édité dans vos méthodes de délégué. Le clavier devrait s'afficher lorsque l'utilisateur touche le champ de texte. Je l'ai fait fonctionner comme ceci. J'espère que cela vous aidera.

0 votes

Il se trouve que j'aime cette solution. Si vous configurez votre champ de texte à l'avance avec CGRectZero comme un cadre, assurez-vous de configurer le cadre de votre champ de texte avant de l'ajouter à la hiérarchie des vues. Obtention de la vue du contenu de la cellule frame la propriété est notamment utile pour une telle tâche.

0 votes

Dans mon cas, il a suffi de remplacer cell.addsubview par cell.contentView.addSubview pour y parvenir...

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X