Я опубликую правильное решение в нижней части страницы на тот случай, если кто-то проявит смелость (или достаточно отчаялся), чтобы прочитать эту статью.
Вот репозиторий gitHub для тех, кто не хочет читать весь этот текст: resizableTextView
Это работает с iOs7 (и я верю, что это будет работать с iOs8) и с autolayout. Вам не нужны магические числа, отключить макет и тому подобное. Краткое и элегантное решение.
Я думаю, что весь код, связанный с ограничениями, должен идти в updateConstraints
метод. Итак, давайте сделаем наши собственные ResizableTextView
.
Первая проблема, с которой мы здесь сталкиваемся, заключается в том, что мы не знаем реального размера контента перед viewDidLoad
методом. Мы можем взять длинный и ошибочный путь и рассчитать его на основе размера шрифта, разрывов строк и т. Д. Но нам нужно надежное решение, поэтому мы сделаем:
CGSize contentSize = [self sizeThatFits:CGSizeMake(self.frame.size.width, FLT_MAX)];
Так что теперь мы знаем реальный размер контента независимо от того, где мы находимся: до или после viewDidLoad
. Теперь добавьте ограничение высоты для textView (через раскадровку или код, независимо от того, как). Мы скорректируем это значение с помощью нашего contentSize.height
:
[self.constraints enumerateObjectsUsingBlock:^(NSLayoutConstraint *constraint, NSUInteger idx, BOOL *stop) {
if (constraint.firstAttribute == NSLayoutAttributeHeight) {
constraint.constant = contentSize.height;
*stop = YES;
}
}];
Последнее, что нужно сделать, это сказать суперклассу updateConstraints
.
[super updateConstraints];
Теперь наш класс выглядит так:
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];
}
Красиво и чисто, правда? И вам не нужно иметь дело с этим кодом в ваших контроллерах !
Но ждать!
У НЕТ АНИМАЦИИ!
Вы можете легко анимировать изменения, чтобы textView
плавно растягиваться. Вот пример:
[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];