42 votes

Comment faire une UITableViewCell avec une UITextView à l'intérieur, qui ajuste sa hauteur de façon dynamique, sur la base de UITextView?

Je souhaite une vue table avec un comportement similaire à celui de l'application iPhone Contacts d'Apple: une cellule uitableview avec une vue uitextview à l'intérieur. Ainsi, lorsque j'écris dans uitextview, uitextview augmente sa hauteur et, en conséquence, la cellule uitableview ajuste dynamiquement sa la taille. J'ai cherché sur tout le Web, ne trouvant que des solutions partielles et un manque de code exemple!

aidez-moi s'il vous plaît je suis désespéré

Tony

37voto

Ajay Sharma Points 4320

En regardant cela,vous devez être un peu délicat. Vous avez besoin de calculer la hauteur de la textView et de manière dynamique en fonction de la Hauteur de la TextView,vous avez besoin de revenir à la Hauteur de la cellule..

Il est très facile et quelque peu Délicat..

C'est le code qui vous permet de calculer la taille de la chaîne....

De la première à obtenir la taille de la Chaîne

NSString *label =  @"Sample String to get the Size for the textView Will definitely work ";
CGSize stringSize = [label sizeWithFont:[UIFont boldSystemFontOfSize:15]
                      constrainedToSize:CGSizeMake(320, 9999)
                          lineBreakMode:UILineBreakModeWordWrap];

over here ....
NSLog(@"%f",stringSize.height);

Deuxièmement, de créer dynamiquement le textView dans la cellule..donner la stringSize.hauteur

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *CellIdentifier = @"Cell";

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

    NSDictionary *d=(NSDictionary *)[self.menuArray objectAtIndex:indexPath.section];

    NSString *string = [d valueForKey:@"Description"];
    CGSize stringSize = [string sizeWithFont:[UIFont boldSystemFontOfSize:15] constrainedToSize:CGSizeMake(320, 9999) lineBreakMode:UILineBreakModeWordWrap];

    UITextView *textV=[[UITextView alloc] initWithFrame:CGRectMake(5, 5, 290, stringSize.height+10)];
    textV.font = [UIFont systemFontOfSize:15.0];
    textV.text=string;
    textV.textColor=[UIColor blackColor];
    textV.editable=NO;
    [cell.contentView addSubview:textV];
    [textV release];

    return cell;
}


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

    NSDictionary *d=(NSDictionary *)[self.menuArray objectAtIndex:indexPath.section];
    NSString *label =  [d valueForKey:@"Description"];
    CGSize stringSize = [label sizeWithFont:[UIFont boldSystemFontOfSize:15]
                          constrainedToSize:CGSizeMake(320, 9999) 
                              lineBreakMode:UILineBreakModeWordWrap];

    return stringSize.height+25;

} 

Après avoir donné beaucoup de peine pour mes doigts,......Je pense que c'est assez de code...& vont sûrement aider à résoudre votre problème..

Bonne Chance

11voto

TomSwift Points 22012

Créer un personnalisé UITableViewCell et ajouter votre UITextView de la cellule contentView.

Dans LayoutSubviews, ensemble textView.cadre à la cellule contentView.limites (ou faire une autre mise en page personnalisée).

Lorsque le textView de la modification de contenu (découvert via UITextViewDelegate), de faire deux choses:

1) appelez [tableView beginUpdates]; [tableView endUpdates]; Cela va forcer l'affichage de la table de recalculer la hauteur pour toutes les cellules (appellera tableView:heightForRowAtIndexPath:). Si votre portable est le délégué pour le textView, alors vous aurez à comprendre comment obtenir un pointeur vers la tableView, mais il existe quelques moyens pour y parvenir. Ou vous pourriez faire le délégué de votre vue-contrôleur...

2) quand est - tableView:heightForRowAtIndexPath: est appelé pour cette cellule, le retour de la textView.contentSize.height. Vous pouvez obtenir votre téléphone portable à partir d'ici, en appelant [tableView cellForRowAtIndexPath]; Ou si vous avez juste une de ces cellules, puis cache un pointeur dans votre viewController.

3voto

weesplodge Points 140

Le seul problème que j'ai trouvé avec l'acceptées réponse est que nous sommes attribution de la UITextView à chaque fois. J'ai trouvé que cela soulevait des problèmes avec la saisie dans la vue et d'avoir le texte de la mise à jour immédiatement et aussi garder la vue en tant que premier répondant. Quand j'ai essayé de recharger la cellule avec la nouvelle hauteur, il serait alors essayez d'ajouter un nouveau textView.

Parce que de ce que j'ai trouvé une méthode légèrement différente pour atteindre le même but. Nous espérons que cette prise différente pourrait aider les gens qui ont de la difficulté à mettre en œuvre le code ci-dessus.

1) Dans le fichier d'en-tête de définir une variable pour la hauteur du texte et le textView:

UITextView * _textView;
NSInteger _textHeight;

Définition d'une variable signifie que nous pouvons nous charger de la vue à une certaine hauteur, si nous sommes le chargement du texte dans le textView et réduit également la complexité.

2) Charger le texte de la vue et de l'ajouter à notre cellule

_textView = [[UITextView alloc] init];
_textView.delegate = self;
_textView.returnKeyType = UIReturnKeyDone;
_textView.font = [UIFont fontWithName:@"Helvetica" size:16];

if (![_user metaStringForKey:bBioKey].length) {
    _textView.text = @"Placeholder text";
    _textView.textColor = [UIColor lightGrayColor];
}


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

    if (indexPath == 0) { // Add logic to choose the correct cell

        if (_textView.superview != cell) {

            [cell addSubview:_textView];     

            _textView.keepTopInset.equal = KeepRequired(7);
            _textView.keepBottomInset.equal = KeepRequired(7);
            _textView.keepRightInset.equal = KeepRequired(10);
            _textView.keepLeftInset.equal = KeepRequired(70);
            }
        }
    }
}

À l'aide de keeplayout nous a permis de garder notre textfield pour toujours rester à la même hauteur que la cellule. Nous sommes également à seulement jamais l'ajout de notre UITextView une fois.

3) Ajouter le code pour calculer la hauteur du texte

- (NSInteger)getHeightOfBio: (NSString *)text {

    UILabel * gettingSizeLabel = [[UILabel alloc] init];
    gettingSizeLabel.font = [UIFont fontWithName:@"Helvetica" size:16];
    gettingSizeLabel.text = text;
    gettingSizeLabel.numberOfLines = 0;
    CGSize maximumLabelSize = CGSizeMake(240, 9999); // this width will be as per your requirement

    CGSize expectedSize = [gettingSizeLabel sizeThatFits:maximumLabelSize];

    return expectedSize.height;
}

J'ai essayé beaucoup et trouvé que c'était le meilleur

4) Ajoutez un peu de logique dans la hauteur de la cellule de rendre l'utilisation de ce:

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

    if (indexPath.row == 0) { // Set the height for our changing textView

        return 30 + [self getHeightOfBio:_textView.text];
    }

    return 44;
}

Évident, nous avons besoin d'un peu plus de hauteur que notre texte de hauteur, alors j'ai ajouté un coussin supplémentaire montant qui peut être expérimenté.

5) l'Actualisation de la vue à chaque fois qu'un caractère est tapé pour vérifier si nous avons besoin d'augmenter la taille:

- (void)textViewDidChange:(UITextView *)textView {

    if ([self getHeightOfText:textView.text] != _textHeight) {

       _textHeight = [self getHeightOfText:textView.text];

       [self.tableView beginUpdates];
       [self.tableView endUpdates];
    }
}

Dans cette section, nous obtenons la hauteur du texte à chaque fois que l'utilisateur tape.

Ensuite, si nous utilisons notre valeur stockée et de comparer la valeur actuelle de la valeur stockée. Évidemment, si ils sont le même, alors il n'y a pas de point dans l'actualisation de la vue. Si ils sont différents de nous mettre à jour la valeur, puis actualiser notre table.

Ce peu, j'ai trouvé une bonne réponse sur stackOverflow montrant comment nous pouvons actualiser uniquement les hauteurs de la table au lieu de la cellule elle-même. Pourquoi actualiser la cellule lorsque nous n'avons pas besoin? Cela signifie qu'une fois que cela s'appelle la hauteur de la cellule est mise à jour et il augmente bien.

De toute façon, j'ai trouvé que ça fonctionnait très bien et était assez simple qui peut être mis en place ou ont les différentes parties et de les mettre dans d'autres peuples morceaux de code.

Accessoires pour la accepté de répondre à ce qui a été pillé pour diverses pièces le long du chemin, mais j'espère aussi que cela permet de répondre à certaines personnes qui ont les mêmes difficultés que j'ai eu.

1voto

dennisreimann Points 431

J'ai écrit mes connaissances et ma solution pour calculer la hauteur UITableViewCell sur la base d'une UITextView interne sur mon blog. Cet article contient le code qui fonctionne pour les applications universelles, à la fois les styles d'affichage de table et l'autorotation.

1voto

onegray Points 2226

Enfin je l'ai eu à travailler. Le principal problème est de savoir comment obtenir de la cellule à l' contentView largeur correcte. Codé en dur largeur ne fonctionne pas pour tous les cas, car il peut varier en conséquence de la plaine/groupés tableau de style, les accessoires ajoutés, ou paysage/portrait. La seule façon d'obtenir 100% de bonne largeur est de lui demander de la cellule de l'objet. J'ai donc créer la cellule de droite, en heightForRowAtIndexPath et de le stocker dans le cache, puis cette mise en cache de la cellule seront retournés par cellForRowAtIndexPathméthode. Un autre problème est de savoir comment la force de la cellule à la disposition de ses sous-vues avant de l'utiliser. Il peut être fait si nous temporaires ajouter de la cellule à l' tableView et mise à jour de la cellule de trame avec tabelViews'de largeur. Après que tous les sous-vues sera relooké dans le droit chemin. Ici est de savoir comment je l'ai eu à travailler dans mon TableKit de la bibliothèque.

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