Как мне определить размер UITextView для его содержимого?

521

Есть ли хороший способ настроить размер, UITextViewчтобы соответствовать его содержанию? Скажем, например, у меня есть, UITextViewкоторый содержит одну строку текста:

"Hello world"

Затем я добавляю еще одну строку текста:

"Goodbye world"

Есть ли хороший способ в Cocoa Touch, чтобы получить тот, rectкоторый будет содержать все строки в текстовом представлении, чтобы я мог соответствующим образом настроить родительский вид?

В качестве другого примера посмотрите на поле заметок для событий в приложении «Календарь» - обратите внимание, как ячейка (и UITextViewсодержащаяся в ней) расширяется, чтобы содержать все строки текста в строке заметок.

drewh
источник
пожалуйста, попробуйте обновить правильный ответ, поскольку принятый ответ приводит к ненужным вычислениям, теперь для этой проблемы есть свойство contentSize.
Хуан Боэро

Ответы:

610

Это работает как для iOS 6.1, так и для iOS 7:

- (void)textViewDidChange:(UITextView *)textView
{
    CGFloat fixedWidth = textView.frame.size.width;
    CGSize newSize = [textView sizeThatFits:CGSizeMake(fixedWidth, MAXFLOAT)];
    CGRect newFrame = textView.frame;
    newFrame.size = CGSizeMake(fmaxf(newSize.width, fixedWidth), newSize.height);
    textView.frame = newFrame;
}

Или в Swift (Работает с Swift 4.1 в iOS 11)

let fixedWidth = textView.frame.size.width
let newSize = textView.sizeThatFits(CGSize(width: fixedWidth, height: CGFloat.greatestFiniteMagnitude))
textView.frame.size = CGSize(width: max(newSize.width, fixedWidth), height: newSize.height)

Если вам нужна поддержка iOS 6.1, вам также следует:

textview.scrollEnabled = NO;
jhibberd
источник
1
Протестировано на iOS 7 для изменения размера UITextView в UITableViewCell. Работает действительно отлично. Это единственный ответ, который наконец-то сработал для меня. Спасибо!
Алекс
37
Мне нужно textview.scrollEnabled = NO;было предотвратить обрезание текста даже в iOS 7.
Брайан
19
Я рекомендую использовать CGFLOAT_MAXмакрос вместо MAXFLOAT. Правильно для обеих 32/64 битных платформ.
Эонил
3
Тот, кто сталкивается с небольшими колебаниями перед входом в следующую строку, добавляет этот `NSRange bottom = NSMakeRange (textView.text.length -1, 1); [textView scrollRangeToVisible: bottom]; `
ajay_nasa
4
Почему в версии Swift есть два отдельных вызова sizeThatFits (...)? Для чего первая строка?
неконари
576

Это больше не работает на iOS 7 или выше

На самом деле существует очень простой способ изменить размер UITextViewсодержимого до его правильной высоты. Это можно сделать с помощью UITextView contentSize.

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

Одна вещь , чтобы отметить , что правильный contentSizeдоступен только послеUITextView того, как была добавлена к просмотру с addSubview. До этого он равенframe.size

Это не будет работать, если включена автоматическая разметка. При автоматической компоновке общий подход заключается в использовании sizeThatFitsметода и обновлении constantзначения ограничения высоты.

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

heightConstraint это ограничение макета, которое вы обычно устанавливаете с помощью IBOutlet, связывая свойство с ограничением высоты, созданным в раскадровке.


Просто добавьте к этому удивительному ответу 2014, если вы:

[self.textView sizeToFit];

есть разница в поведении только с iPhone6 ​​+ :

введите описание изображения здесь

Только с 6+ (не с 5 или 6) он добавляет «еще одну пустую строку» в UITextView. «Решение RL» прекрасно это исправляет:

CGRect _f = self.mainPostText.frame;
_f.size.height = self.mainPostText.contentSize.height;
self.mainPostText.frame = _f;

Исправляет проблему «лишней линии» на 6+.

Ронни Лью
источник
2
Ты спас мой день. Я боролся с расширением функций класса selfCalculating, забыв об этом. Благодарю вас.
Лукаш
4
Ага! Я устанавливал высоту текстового представления и затем настраивал высоту содержащего представления. Видимо, когда я это сделал, высота представления текста корректировалась. Установка вмещающей высоты представления сначала заставляет вещи работать как ожидалось (или, лучше, надеялись).
Hot Licks
11
Использование [_textView sizeToFit] обновляет свойство contentSize, устраняя необходимость предварительно добавлять его в scrollView.
Родриго
1
Если вы используете autolayout, обратитесь layoutIfNeededк суперпредставлению. Тогда вы можете получить высоту от contentSize.
phatmann
4
Речь идет об изменении размера внешнего контейнера. Это поведение изменилось в iOS 7. Я показываю в связанном вопросе, где добавить sizeToFit и layoutIfNeeded.
Хенрик Эрландссон
93

Для динамического определения размера UITextViewвнутри UITableViewCellя обнаружил, что следующая комбинация работает в Xcode 6 с iOS 8 SDK:

  • Добавить UITextViewкUITableViewCell и ограничьте его по сторонам
  • Установите для свойства UITextView' . При включенной прокрутке кадр не зависит от размера его содержимого, но при отключенной прокрутке между ними существует связь.scrollEnabledNOUITextView
  • Если ваша таблица использует исходную высоту строки по умолчанию, равную 44, тогда она автоматически вычислит высоту строки, но если вы изменили высоту строки по умолчанию на что-то другое, вам может потребоваться вручную включить автоматический расчет высоты строки в viewDidLoad:

    tableView.estimatedRowHeight = 150;
    tableView.rowHeight = UITableViewAutomaticDimension;

Для динамического определения размера только для чтения UITextView, вот и все. Если вы разрешаете пользователям редактировать текст в вашем UITextView, вам также необходимо:

  • Реализуйте textViewDidChange:метод UITextViewDelegateпротокола и попросите tableViewперерисовывать себя каждый раз, когда текст редактируется:

    - (void)textViewDidChange:(UITextView *)textView;
    {
        [tableView beginUpdates];
        [tableView endUpdates];
    }
  • И не забудьте установить UITextViewделегата где-нибудь, в Storyboardили вtableView:cellForRowAtIndexPath:

Бретт Дональд
источник
Лучший ответ для меня. Отлично сработало, и в iOS 5 был добавлен UITableViewAutomaticDimension, поэтому он обратно совместим.
smmelzer
4
У меня не совсем получилось. Метод textViewDidChange вызывает отскок моего табличного представления каждый раз, когда я набираю символ. Я предлагаю вместо использования этого метода в методе tableView: cellForRowAtIndexPath для строки с текстовым представлением, если вы находитесь в режиме только для чтения, установите для .scrollEnabled значение NO, и если вы находитесь в наборе для редактирования. прокрутка включена ДА. Таким образом, при простом отображении он всегда будет отображать полный текст, а при редактировании он будет начинаться с полного текста, а при добавлении дополнительного текста будет оставаться тот же размер, что и предыдущий текст, прокручиваемый сверху
SimonTheDiver
3
Кроме того, я добавил ограничение> = высоты в текстовое представление, так как пустое текстовое поле не имело высоты и не могло быть нажато, чтобы начать редактирование.
SimonTheDiver
Отличное решение. Для меня это tableView.rowHeight = UITableViewAutomaticDimensionбыло ненужным.
Кристофер Пикслей
Еще раз спасибо Бретт Дональд! Я забыл, как это сделать, и нашел ваш ответ еще раз через год 😀.
Эрик Коннер
76

Очень простое в использовании решение с использованием кода и раскадровки.

По коду

textView.scrollEnabled = false

По раскадровке

Снимите флажок Включить прокрутку

введите описание изображения здесь

Не нужно ничего делать кроме этого.

Alok
источник
5
Этот ответ правильный. В StoryBoard у вас есть TextView AutoSize, как и UILabel. Все, что нам нужно сделать, это установить scrollEnabled = false.
Пнавк
4
По сути, это правильно: если вы используете ограничения Autolayout и отключили прокрутку, все работает.
Дэн Розенстарк
2
Большое спасибо. Это было так просто, просто отключите прокрутку в раскадровке или коде, это будет похоже на UILabel со строками 0.
samir105
@Mansuu .... Это не гарантированное решение, так как есть вещи, которые вы можете сделать, чтобы переопределить внутренний размер контента, и если вы измените текст после того, как представление выложено, оно не обновится, если вы не установите это вверх тоже. Но эти вещи остаются верными для установки numberOfLines = 0 и в текстовом поле. Если это не работает, возможно, у вас есть другие ограничения, которые неявно устанавливают высоту.
Джейк Т.
2
@iOS, если вы добавляете ограничение по высоте, тогда делайте приоритет ограничения более низким, иначе это не будет работать.
Alok
61

Свифт:

textView.sizeToFit()
Хуан Боэро
источник
14
Кроме того, я обнаружил, что для этого нужно было установить прокрутку на false. textView.scrollEnabled = false
tmarkiewicz
1
Не забывайте вызывать textView.layoutIfNeeded () после textView.sizeToFit ()
Даниэль Кута
5
@tmarkiewicz Это работает, когда текст помещается на экране вашего устройства, но это будет проблемой, когда ваш текст будет больше, чем пространство на экране. Вы не сможете прокрутить его, чтобы увидеть остальную часть текста.
Франциско Ромеро
Это ответ !!! Нет необходимости в более сложных решениях !!! @FranciscoRomero Почему бы не разместить текстовое представление в ячейке таблицы или в представлении совокупности, тогда вы всегда можете прокрутить представление таблицы или совокупности ....
Бен Смит
23

По моему (ограниченному) опыту,

- (CGSize)sizeWithFont:(UIFont *)font forWidth:(CGFloat)width lineBreakMode:(UILineBreakMode)lineBreakMode

не учитывает символы новой строки, поэтому вы можете получить намного короче, CGSizeчем требуется на самом деле.

- (CGSize)sizeWithFont:(UIFont *)font constrainedToSize:(CGSize)size

похоже, уважает новые строки.

Кроме того, текст на самом деле не отображается в верхней части UITextView. В моем коде я установил новую высоту на UITextView24 пикселя больше, чем высота, возвращаемая sizeOfFontметодами.

user63934
источник
3
Это получает размер, как если бы он рисовал текст на UILabel. Если вы установите этот размер для фрейма uitextview, у вас все равно будет некоторая необходимая прокрутка.
Кевлар
22

В iOS6 вы можете проверить contentSizeсвойство UITextView сразу после установки текста. В iOS7 это больше не будет работать. Если вы хотите восстановить это поведение для iOS7, поместите следующий код в подкласс UITextView.

- (void)setText:(NSString *)text
{
    [super setText:text];

    if (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_6_1) {
        CGRect rect = [self.textContainer.layoutManager usedRectForTextContainer:self.textContainer];
        UIEdgeInsets inset = self.textContainerInset;
        self.contentSize = UIEdgeInsetsInsetRect(rect, inset).size;
    }
}
phatmann
источник
2
Где я могу прочитать больше об этом? Я полностью потерян в отношении, казалось бы, нового поведения в iOS 7 по этому поводу.
Stian Høiland
В чем смысл переменной CGSize size?
ч. В
Я удалил размер, он не должен был быть там.
phatmann
18

Я опубликую правильное решение в нижней части страницы на тот случай, если кто-то проявит смелость (или достаточно отчаялся), чтобы прочитать эту статью.

Вот репозиторий 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];
Никита Тук
источник
4
Используйте CGFLOAT_MAX, нет FLT_MAX.
Роб Майофф
Хотел бы я дать вам больше одного голоса за это потрясающее решение !!
Скутер
13

Ты пробовал [textView sizeThatFits:textView.bounds] ?

Редактировать: sizeThatFits возвращает размер, но фактически не изменяет размер компонента. Я не уверен, что это то, что вы хотите, или если [textView sizeToFit]это больше, что вы искали. В любом случае, я не знаю, будет ли он идеально соответствовать контенту, который вы хотите, но это первое, что нужно попробовать.

Майк МакМастер
источник
2
sizetofit спасает день
michaelsnowden
9

Другой метод - это поиск размера, который определенная строка займет, используя NSStringметод:

-(CGSize)sizeWithFont:(UIFont *)font constrainedToSize:(CGSize)size

Это возвращает размер прямоугольника, который соответствует данной строке с данным шрифтом. Передайте размер с желаемой шириной и максимальной высотой, а затем вы можете посмотреть на высоту, возвращаемую в соответствии с текстом. Существует версия, которая позволяет также указать режим разрыва строки.

Затем вы можете использовать возвращенный размер, чтобы изменить размер вашего представления, чтобы соответствовать.

Кодовый наркоман
источник
8

Если у вас нет UITextViewудобного устройства (например, вы измеряете ячейки табличного представления), вам придется рассчитать размер, измерив строку, а затем с учетом 8 пт отступов на каждой стороне a UITextView. Например, если вы знаете желаемую ширину вашего текстового представления и хотите определить соответствующую высоту:

NSString * string = ...;
CGFloat textViewWidth = ...;
UIFont * font = ...;

CGSize size = CGSizeMake(textViewWidth - 8 - 8, 100000);
size.height = [string sizeWithFont:font constrainedToSize:size].height + 8 + 8;

Здесь каждая 8 учитывает один из четырех заполненных краев, а 100000 служит очень большим максимальным размером.

На практике вы можете добавить дополнительный font.leadingк высоте; это добавляет пустую строку ниже вашего текста, которая может выглядеть лучше, если есть визуально тяжелые элементы управления непосредственно под текстовым представлением.

Брент Роял-Гордон
источник
идеальный результат в iOS 8.1
Logic
Паддинг был для меня ключом
thibaut noah
8

Мы можем сделать это с помощью ограничений.

  1. Установите ограничения высоты для UITextView. введите описание изображения здесь

2. Создайте IBOutlet для этого ограничения высоты.

 @property (weak, nonatomic) IBOutlet NSLayoutConstraint *txtheightconstraints;

3. не забудьте установить делегат для вашего textview.

4.

-(void)textViewDidChange:(UITextView *)textView
{
    CGFloat fixedWidth = textView.frame.size.width;
    CGSize newSize = [textView sizeThatFits:CGSizeMake(fixedWidth, MAXFLOAT)];
    CGRect newFrame = textView.frame;
    newFrame.size = CGSizeMake(fmaxf(newSize.width, fixedWidth), newSize.height);
    NSLog(@"this is updating height%@",NSStringFromCGSize(newFrame.size));
    [UIView animateWithDuration:0.2 animations:^{
                  _txtheightconstraints.constant=newFrame.size.height;
    }];

}

тогда обновите свое ограничение как это :)

Кишоре Кумар
источник
это фантастическое прозвище!
Толстяк
Установка константы должна сопровождаться [textView layoutIfNeeded]; в блоке анимации. (Анимации с автопоставкой делают это так.)
Will Larche
7

Достаточно следующих вещей:

  1. Только не забудьте установить скроллинг включен в NO для вашего UITextView:

введите описание изображения здесь

  1. Правильно установите ограничения Auto Layout.

Вы можете даже использовать UITableViewAutomaticDimension.

Бартломей Семанчик
источник
6

В сочетании с ответом Майка МакМастера вы можете сделать что-то вроде:

[myTextView setDelegate: self];

...

- (void)textViewDidChange:(UITextView *)textView {
  if (myTextView == textView) {
     // it changed.  Do resizing here.
  }
}
Olie
источник
6

Я нашел способ изменить высоту текстового поля в соответствии с текстом внутри него, а также расположить метку под ним в зависимости от высоты текстового поля! Вот код

UITextView *_textView = [[UITextView alloc] initWithFrame:CGRectMake(10, 10, 300, 10)];
NSString *str = @"This is a test text view to check the auto increment of height of a text view. This is only a test. The real data is something different.";
_textView.text = str;

[self.view addSubview:_textView];
CGRect frame = _textView.frame;
frame.size.height = _textView.contentSize.height;
_textView.frame = frame;

UILabel *lbl = [[UILabel alloc] initWithFrame:CGRectMake(10, 5 + frame.origin.y + frame.size.height, 300, 20)];
lbl.text = @"Hello!";
[self.view addSubview:lbl];
Dheeraj
источник
Здесь '5' в y-координате UILabel - это промежуток, который я хочу между textView и Label.
deeraj
6

Ребята, использующие autolayout, и ваш sizetofit не работает, тогда, пожалуйста, проверьте ограничение ширины один раз. Если вы пропустили ограничение ширины, высота будет точной.

Нет необходимости использовать любой другой API. только одна строка решит все проблемы.

[_textView sizeToFit];

Здесь я интересовался только высотой, сохраняя фиксированную ширину и пропустив ограничение ширины моего TextView в раскадровке.

И это должно было показать динамический контент от сервисов.

Надеюсь, что это может помочь ..

Swaroop S
источник
6

Начиная с iOS 8, можно использовать функции автоматического макета UITableView для автоматического изменения размера UITextView без какого-либо пользовательского кода вообще. Я поместил проект в github, который демонстрирует это в действии, но вот ключ:

  1. У UITextView должна быть отключена прокрутка, которую вы можете сделать программно или через конструктор интерфейса. Размер не изменится, если включена прокрутка, потому что прокрутка позволяет просматривать содержимое большего размера.
  2. В viewDidLoad для UITableViewController вы должны установить значение дляtimateRowHeight, а затем установить rowHeightв UITableViewAutomaticDimension.

- (void)viewDidLoad {
    [super viewDidLoad];
    self.tableView.estimatedRowHeight = self.tableView.rowHeight;
    self.tableView.rowHeight = UITableViewAutomaticDimension;
}
  1. Цель развертывания проекта должна быть iOS 8 или выше.
Чак Круцингер
источник
1
Подобные ответы не приветствуются. Вы должны опубликовать соответствующий код здесь.
Антзи
5

Я просмотрел все ответы и все держал фиксированную ширину и корректировал только высоту. Если вы хотите отрегулировать также ширину, вы можете очень легко использовать этот метод:

поэтому при настройке текстового представления отключите прокрутку

textView.isScrollEnabled = false

и затем в методе делегата func textViewDidChange(_ textView: UITextView)добавьте этот код:

func textViewDidChange(_ textView: UITextView) {
    let newSize = textView.sizeThatFits(CGSize(width: CGFloat.greatestFiniteMagnitude, height: CGFloat.greatestFiniteMagnitude))
    textView.frame = CGRect(origin: textView.frame.origin, size: newSize)
}

Выходы:

введите описание изображения здесь

введите описание изображения здесь

Питер Стайгер
источник
Метод делегата не называется @Peter Stajger
Mansuu ....
4

Это хорошо работало, когда мне нужно было сделать текст UITextViewвписывающимся в определенную область:

// Текст должен быть уже добавлен в подпредставление, иначе размер содержимого будет неправильным.

- (void) reduFontToFit: (UITextView *) tv {
    UIFont * font = tv.font;
    double pointSize = font.pointSize;

    while (tv.contentSize.height> tv.frame.size.height && pointSize> 7.0) {
        pointSize - = 1,0;
        UIFont * newFont = [UIFont fontWithName: font.fontName size: pointSize];
        tv.font = newFont;
    }
    if (pointSize! = font.pointSize)
        NSLog (@ "шрифт до% .1f от% .1f", pointSize, tv.font.pointSize);
}
Билл Чесвик
источник
4

вот быстрая версия @jhibberd

    let cell:MsgTableViewCell! = self.tableView.dequeueReusableCellWithIdentifier("MsgTableViewCell", forIndexPath: indexPath) as? MsgTableViewCell
    cell.msgText.text = self.items[indexPath.row]
    var fixedWidth:CGFloat = cell.msgText.frame.size.width
    var size:CGSize = CGSize(width: fixedWidth,height: CGFloat.max)
    var newSize:CGSize = cell.msgText.sizeThatFits(size)
    var newFrame:CGRect = cell.msgText.frame;
    newFrame.size = CGSizeMake(CGFloat(fmaxf(Float(newSize.width), Float(fixedWidth))), newSize.height);
    cell.msgText.frame = newFrame
    cell.msgText.frame.size = newSize        
    return cell
Фарид Алнамрути
источник
6
Вопрос действительно не зависит от языка. Действительно ли необходимо вернуться назад и написать быстрые порты для всех ответов на вопросы, связанные с UIKit? Похоже, это делает для шумного разговора.
eremzeit
проблема в том, что в большинстве этих вопросов нет определенного языка программирования, поэтому вы найдете его в Google, даже если вы ищете быстрый язык
Fareed Alnamrouti
4

отключить прокрутку

добавить содержание

и добавьте свой текст

[yourTextView setText:@"your text"];
[yourTextView layoutIfNeeded];

если вы используете, UIScrollViewвы должны добавить это тоже;

[yourScrollView layoutIfNeeded];

-(void)viewDidAppear:(BOOL)animated{
    CGRect contentRect = CGRectZero;

    for (UIView *view in self.yourScrollView.subviews) {
         contentRect = CGRectUnion(contentRect, view.frame);
    }
    self.yourScrollView.contentSize = contentRect.size;
}
alicanozkara
источник
3

Для iOS 7.0 вместо установки frame.size.heightна contentSize.height(который в настоящее время ничего не делает) использовать [textView sizeToFit].

Смотрите этот вопрос .

Стиан Хойланд
источник
2

Использование UITextViewDelegate - самый простой способ:

func textViewDidChange(_ textView: UITextView) {
    textView.sizeToFit()
    textviewHeight.constant = textView.contentSize.height
}
f0go
источник
1

Надеюсь это поможет:

- (void)textViewDidChange:(UITextView *)textView {
  CGSize textSize = textview.contentSize;
  if (textSize != textView.frame.size)
      textView.frame.size = textSize;
}
Доктор Марти
источник
Это не работает! Это вызывает ошибку: «lvalue требуется как левый операнд присваивания»
Левиафан
Вы можете назначить только textView.frame.
jweyrich
1

если кто-нибудь еще доберется до меня, это решение будет работать для меня, 1 «Ронни Лью» +4 «user63934» (мой текст приходит из веб-службы): обратите внимание на 1000 (ничто не может быть таким большим «в моем случае»)

UIFont *fontNormal = [UIFont fontWithName:FONTNAME size:FONTSIZE];

NSString *dealDescription = [client objectForKey:@"description"];

//4
CGSize textSize = [dealDescription sizeWithFont:fontNormal constrainedToSize:CGSizeMake(containerUIView.frame.size.width, 1000)];

CGRect dealDescRect = CGRectMake(10, 300, containerUIView.frame.size.width, textSize.height);

UITextView *dealDesc = [[[UITextView alloc] initWithFrame:dealDescRect] autorelease];

dealDesc.text = dealDescription;
//add the subview to the container
[containerUIView addSubview:dealDesc];

//1) after adding the view
CGRect frame = dealDesc.frame;
frame.size.height = dealDesc.contentSize.height;
dealDesc.frame = frame;

И это ... Ура

Alejo JM
источник
1

Лучший способ, который я обнаружил, - изменить размер UITextView в соответствии с размером текста.

CGSize textViewSize = [YOURTEXTVIEW.text sizeWithFont:[UIFont fontWithName:@"SAMPLE_FONT" size:14.0]
                       constrainedToSize:CGSizeMake(YOURTEXTVIEW.frame.size.width, FLT_MAX)];

или вы можете использовать

CGSize textViewSize = [YOURTEXTVIEW.text sizeWithFont:[UIFont fontWithName:@"SAMPLE_FONT" size:14.0]
                       constrainedToSize:CGSizeMake(YOURTEXTVIEW.frame.size.width, FLT_MAX) lineBreakMode:NSLineBreakByTruncatingTail];
Манжу
источник
1

Для тех, кто хочет, чтобы текстовый вид действительно двигался вверх и поддерживал позицию нижней строки

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

if(frame.size.height > textView.frame.size.height){
    CGFloat diff = frame.size.height - textView.frame.size.height;
    textView.frame = CGRectMake(0, textView.frame.origin.y - diff, textView.frame.size.width, frame.size.height);
}
else if(frame.size.height < textView.frame.size.height){
    CGFloat diff = textView.frame.size.height - frame.size.height;
    textView.frame = CGRectMake(0, textView.frame.origin.y + diff, textView.frame.size.width, frame.size.height);
}
Гал Бланк
источник
1

Единственный работающий код - это тот, который использует «SizeToFit», как в ответе jhibberd выше, но на самом деле он не подхватит, если вы не вызовете его в ViewDidAppear или не подключите его к событию изменения текста UITextView.

Мухаммед Зекралла
источник
1

Основываясь на ответе Никиты Тука, я пришел к следующему решению в Swift, которое работает на iOS 8 с autolayout:

    descriptionTxt.scrollEnabled = false
    descriptionTxt.text = yourText

    var contentSize = descriptionTxt.sizeThatFits(CGSizeMake(descriptionTxt.frame.size.width, CGFloat.max))
    for c in descriptionTxt.constraints() {
        if c.isKindOfClass(NSLayoutConstraint) {
            var constraint = c as! NSLayoutConstraint
            if constraint.firstAttribute == NSLayoutAttribute.Height {
                constraint.constant = contentSize.height
                break
            }
        }
    }
Apfelsaft
источник
1

Быстрый ответ: следующий код вычисляет высоту вашего textView.

                let maximumLabelSize = CGSize(width: Double(textView.frame.size.width-100.0), height: DBL_MAX)
                let options = NSStringDrawingOptions.TruncatesLastVisibleLine | NSStringDrawingOptions.UsesLineFragmentOrigin
                let attribute = [NSFontAttributeName: textView.font!]
                let str = NSString(string: message)
                let labelBounds = str.boundingRectWithSize(maximumLabelSize,
                    options: NSStringDrawingOptions.UsesLineFragmentOrigin,
                    attributes: attribute,
                    context: nil)
                let myTextHeight = CGFloat(ceilf(Float(labelBounds.height)))

Теперь вы можете установить высоту вашего textView в myTextHeight

RawMean
источник
Извините, что это значит: let attribute = [NSFontAttributeName: textView.text.font!] действительно ли это код Swift без ошибок?) Вы let attribute = [NSFontAttributeName: textView.font!]
имели в