Je posterai la bonne solution au bas de la page au cas où quelqu'un serait courageux (ou assez désespéré) pour lire jusqu'à ce point.
Voici le dépôt gitHub pour ceux qui ne veulent pas lire tout ce texte: resizableTextView
Cela fonctionne avec iOs7 (et je pense que cela fonctionnera avec iOs8) et avec la mise en page automatique. Vous n'avez pas besoin de nombres magiques, désactivez la mise en page et des trucs comme ça. Solution courte et élégante.
Je pense que tout le code lié aux contraintes devrait aller à la updateConstraints
méthode. Alors, faisons le nôtre ResizableTextView
.
Le premier problème que nous rencontrons ici est que nous ne connaissons pas la taille réelle du contenu avant la viewDidLoad
méthode. Nous pouvons prendre une route longue et boguée et la calculer en fonction de la taille de la police, des sauts de ligne, etc. Mais nous avons besoin d'une solution robuste, nous allons donc faire:
CGSize contentSize = [self sizeThatFits:CGSizeMake(self.frame.size.width, FLT_MAX)];
Alors maintenant, nous connaissons le vrai contenu, quelle que soit notre position: avant ou après viewDidLoad
. Ajoutez maintenant une contrainte de hauteur sur textView (via le storyboard ou le code, peu importe comment). Nous ajusterons 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 à la superclasse 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];
}
Joli et propre, non? Et vous n'avez pas à traiter avec ce code dans votre contrôleurs !
Mais attendez!
OU PAS D'ANIMATION!
Vous pouvez facilement animer les modifications pour effectuer un textView
étirement 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];