561 votes

Comment est-ce que je taille un UITextView à son contenu ?

Est-il un bon moyen pour ajuster la taille d'un UITextView à se conformer à son contenu? Dire, par exemple, j'ai un UITextView qui contient une seule ligne de texte:

"Bonjour le monde"

Je puis ajouter une autre ligne de texte:

"Adieu monde"

Est-il un bon moyen de Cocoa Touch pour obtenir le rectangle qui contiendra toutes les lignes de l'affichage de texte, de sorte que je peux ajuster la vue parent en conséquence?

Comme autre exemple, regardez le champ Notes pour les événements dans le Calendrier d'application--notez comment la cellule (et l' UITextView il contient) s'étend à tenir toutes les lignes de texte dans les notes de la chaîne.

644voto

jhibberd Points 1134

Cela fonctionne pour les iOS 6.1 et iOS 7 :

Si vous souhaitez prise en charge d’iOS 6.1 alors vous devriez également :

578voto

Ronnie Liew Points 11112

Il est en fait un moyen très facile de faire un redimensionnement de l' UITextView de sa hauteur correcte pour le contenu. Il peut être fait à l'aide de l' UITextView contentSize.

CGRect frame = _textView.frame;
frame.size.height = _textView.contentSize.height;
_textView.frame = frame;

Une chose à noter est que le bon contentSize est disponible uniquement après l' UITextView a été ajouté à la vue d' addSubview. Avant qu'il soit égal à frame.size

Cela ne fonctionnera pas si la mise en page automatique est SUR. Avec mise en page automatique, l'approche générale consiste à utiliser l' sizeThatFits méthode et mise à jour de l' constant de la valeur sur une hauteur de contrainte.

CGSize sizeThatShouldFitTheContent = [_textView sizeThatFits:_textView.frame.size];
heightConstraint.constant = sizeThatShouldFitTheContent.height;

heightConstraint est une contrainte de mise en page qui vous permet généralement d'installation par l'intermédiaire d'un IBOutlet en reliant la propriété à la hauteur de la contrainte créée dans un storyboard.

24voto

phatmann Points 4153

Dans iOS6, vous pouvez vérifier la `` propriété de UITextView juste après avoir mis le texte. Dans iOS7, cela ne fonctionnera plus. Si vous souhaitez restaurer ce comportement pour iOS7, placez le code suivant dans une sous-classe de UITextView.

24voto

user63934 Points 191

Dans mon expérience (limitée),

ne respecte pas les caractères de saut de ligne, donc vous pouvez vous retrouver avec beaucoup plus court `` que réellement nécessaire.

ne semble pas respecter les sauts de ligne.

En outre, le texte n’est pas réellement rendu au sommet de la . Dans mon code, j’ai mis la nouvelle hauteur de la supérieure à la hauteur retournée par 24 pixels la `` méthodes.

19voto

Nikita Took Points 1055

Je post juste solution au bas de la page au cas où quelqu'un est courageux (ou désespéré assez) lire à ce point.

Voici dépôt gitHub pour ceux qui ne veulent pas lire tout ce texte: resizableTextView

Cela fonctionne avec iOs7 (et je ne crois qu'il va travailler avec iOs8) et avec mise en page automatique. Vous n'avez pas besoin des numéros de magie, de désactiver la mise en page et des trucs comme ça. Courte et élégante solution.

Je pense, que toutes les contraintes liées code doit aller à l' updateConstraints méthode. Donc, nous allons faire notre propre ResizableTextView.

Le premier problème que nous rencontrons ici est que ne sais pas le contenu réel de la taille avant d' viewDidLoad méthode. On peut prendre longtemps et buggy route et de calculer sur la base taille de la police, des sauts de ligne, etc. Mais nous avons besoin d'une solution fiable, de sorte que nous allons faire:

CGSize contentSize = [self sizeThatFits:CGSizeMake(self.frame.size.width, FLT_MAX)];

Alors maintenant, nous savons réel contentSize peu importe où nous sommes: avant ou après l' viewDidLoad. Maintenant ajouter de la hauteur de la contrainte sur textView (via la table de montage ou de code, n'importe comment). Nous allons régler cette valeur avec notre contentSize.height:

[self.constraints enumerateObjectsUsingBlock:^(NSLayoutConstraint *constraint, NSUInteger idx, BOOL *stop) {
    if (constraint.firstAttribute == NSLayoutAttributeHeight) {
        constraint.constant = contentSize.height;
        *stop = YES;
    }
}];

La dernière chose à faire est de dire super - updateConstraints.

[super updateConstraints];

Maintenant, notre classe ressemble à:

ResizableTextView.m

- (void) updateConstraints {
    CGSize contentSize = [self sizeThatFits:CGSizeMake(self.frame.size.width, FLT_MAX)];

    [self.constraints enumerateObjectsUsingBlock:^(NSLayoutConstraint *constraint, NSUInteger idx, BOOL *stop) {
        if (constraint.firstAttribute == NSLayoutAttributeHeight) {
            constraint.constant = contentSize.height;
            *stop = YES;
        }
    }];

    [super updateConstraints];
}

Jolie et propre, droit? Et vous n'avez pas à traiter avec ce code dans vos contrôleurs!

Mais attendez! Y PAS D'ANIMATION!

Vous pouvez facilement animer des changements à apporter textView étirer en douceur. Voici un exemple:

    [self.view layoutIfNeeded];
    // do your own text change here.
    self.infoTextView.text = [NSString stringWithFormat:@"%@, %@", self.infoTextView.text, self.infoTextView.text];
    [self.infoTextView setNeedsUpdateConstraints];
    [self.infoTextView updateConstraintsIfNeeded];
    [UIView animateWithDuration:1 delay:0 options:UIViewAnimationOptionLayoutSubviews animations:^{
        [self.view layoutIfNeeded];
    } completion:nil];

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