Як розмістити розмір UITextView до його вмісту?


521

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

"Hello world"

Потім я додаю ще один рядок тексту:

"Goodbye world"

Чи є в Cocoa Touch хороший спосіб отримати той, rectякий буде містити всі рядки в текстовому вікні, щоб я міг відповідно відрегулювати батьківський вигляд?

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


будь ласка, врахуйте оновлення правильної відповіді, оскільки прийнята веде до зайвих обчислень, тепер для цього питання є властивість 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;

1
Тестовано на iOS 7 для зміни розміру UITextView в UITableViewCell. Працює дійсно чудово. Це єдина відповідь, яка нарешті спрацювала для мене. Дякую!
Олексій

37
Мені потрібно було, textview.scrollEnabled = NO;щоб текст не був відрізаний навіть в iOS 7.
Брайан

19
Я рекомендую використовувати CGFLOAT_MAXмакрос замість MAXFLOAT. Підходить для обох 32/64 бітових платформ.
Еоніл

2
Той, хто стикається з невеликими коливаннями, перш ніж входити в наступний рядок, додає це `NSRange bottom = NSMakeRange (textView.text.length -1, 1); [textView scrollRangeToVisible: bottom]; `
ajay_nasa

4
Чому у версії Swift є два окремих виклику до sizeThatFits (...)? Для чого перший рядок?
nekonari

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
Ти врятував мені день. Я боровся з розширенням функції самостійного підрахунку класу, забувши про це. Дякую тобі.
Лукаш

4
Ага! Я встановлював висоту перегляду тексту, а потім регулював висоту перегляду, що міститься. Мабуть, коли я робив, що висота перегляду тексту була налаштована. Встановлення висоти перегляду, що містить, спочатку змушує роботу працювати так, як очікувалося (або, що краще, сподівалося)
Гарячі лизи

11
Використання [_textView sizeToFit] оновлює властивість contentSize, видаляючи вимогу заздалегідь додати його до scrollView.
Родріго

1
Якщо ви використовуєте автоматичний розклад, зателефонуйте layoutIfNeededна супровід. Тоді ви можете схопити висоту з contentSize.
phatmann

4
Хоча мова йде про зміну розміру зовнішнього контейнера. Така поведінка змінилася в iOS 7. Я показую у пов'язаному питанні, куди слід додати sizeToFit та layoutIfNeeded.
Генрік Ерландссон

93

Щоб зробити динамічне розмір UITextViewвсередині UITableViewCell, я знайшов наступну комбінацію, яка працює в Xcode 6 за допомогою iOS 8 SDK:

  • Додати UITextViewдо UITableViewCellі обмежити його сторін
  • Встановіть режим UITextView«S scrollEnabledвласності NO. Якщо ввімкнено прокрутку, кадр вікна UITextViewне залежить від розміру вмісту, але при відключенні прокрутки існує взаємозв'язок між ними.
  • Якщо ваша таблиця використовує початкову висоту рядка за замовчуванням 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:


Найкраща відповідь для мене. Працював чудово і UITableViewAutomaticDimension був доданий в iOS 5, тому він сумісний із зворотним ходом.
smmelzer

4
Мені не дуже вдалося. Метод textViewDidChange змушує моє перегляд таблиці підстрибувати кожного разу, коли я вводив символ. Що я пропоную, це те, що замість цього методу використовуйте метод tableView: cellForRowAtIndexPath для рядка з текстовим переглядом на ньому, якщо ви перебуваєте в режимі лише для читання .scrollEnabled to NO, і якщо ви перебуваєте в наборі перегляду редагування прокрутка включена до ТАК. Таким чином, при простому відображенні він завжди відображатиме повний текст, а під час редагування він починається з повного тексту, а при додаванні подальшого тексту залишатиметься такого ж розміру, як і попередній текст, який прокручується вгорі
SimonTheDiver

3
Крім того, я додав обмеження висоти до перегляду тексту, оскільки порожнє текстове поле не було висоти, і його не можна було натиснути, щоб почати редагування.
SimonTheDiver

Відмінне рішення. Для мене це tableView.rowHeight = UITableViewAutomaticDimensionбуло непотрібне.
Крістофер Пікслі

Дякую ще раз Бретт Дональд! Я забув, як це зробити, і знову знайшов вашу відповідь через 1 рік 😀.
Ерік Коннер

74

Дуже просте робоче рішення, використовуючи і код, і табло.

За кодексом

textView.scrollEnabled = false

За розповідь

Зніміть прапорець Увімкнути прокрутку

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

Не потрібно нічого крім цього робити.


5
Ця відповідь правильна. У StoryBoard у вас є TextView AutoSize так само, як і UILabel. Все, що нам потрібно зробити, це встановити scrollEnabled = false.
pnavk

4
По суті, це правильно: якщо ви використовуєте обмеження для автоматичного вимикання та вимикаєте прокрутку, все працює.
Дан Розенстарк

2
Дуже дякую. Це було так просто, просто вимкніть прокручування в раскадровці або коді, це буде як UILabel з рядками 0.
samir105

@Mansuu .... Це не гарантоване рішення, оскільки ви можете змінити внутрішній розмір вмісту, і якщо змінити текст після викладу перегляду, він не оновлюється, якщо ви не встановите це вгору теж. Але ці речі залишаються вірними і для встановлення numberOfLines = 0 у текстовому полі. Якщо це не працює, напевно, у вас є інші обмеження, які неявно встановлять висоту.
Джейк Т.

2
@iOS, якщо ви додаєте обмеження по висоті, тоді зробіть пріоритет обмежень нижчим, інакше це не буде працювати.
Алок

61

Швидкий:

textView.sizeToFit()

14
Крім того, я виявив, що мені потрібно встановити функцію прокрутки, щоб увімкнено значення false для цього. textView.scrollEnabled = false
tmarkiewicz

1
Вам слід пам’ятати, щоб зателефонувати textView.layoutIfNeeded () після textView.sizeToFit ()
Даніель Кута

5
@tmarkiewicz Він працює, коли текст розміщується на екрані вашого пристрою, але це буде проблемою, коли ваш текст більший за простір, який є на екрані. Ви не зможете прокрутити його, щоб побачити решту тексту.
Франсіско Ромеро

Це відповідь !!! Немає потреби у складніших рішеннях !!! @FranciscoRomero Чому б не помістити textview у комірку таблиці чи огляд колекціону, тоді ви завжди можете прокручувати подання таблиці чи колекціону ....
Бен Сміт

23

З мого (обмеженого) досвіду,

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

не поважає символи нового рядка, тому ви можете закінчити набагато коротше, CGSizeніж потрібно.

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

здається, поважає нові рядки.

Також текст насправді не відображається у верхній частині UITextView. У своєму коді я встановив, що нова висота UITextViewмає бути на 24 пікселів більша за висоту, повернуту sizeOfFontметодами.


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;
    }
}

2
Де я можу прочитати більше про це? Я повністю втрачений щодо, здавалося б, нової поведінки в iOS 7 щодо цього.
Stian Høiland

У чому значення змінного розміру CGSize?
Чечов

Я видалив розмір, його там не повинно було бути.
phatmann

18

Я розміщую правильне рішення внизу сторінки, якщо хтось сміливий (або достатньо відчайдушний), щоб прочитати до цього моменту.

Ось gitHub repo для тих, хто не хоче читати весь цей текст: resizableTextView

Це працює з iOs7 (і я вірю, що він буде працювати з iOs8) і з авторозміткою. Вам не потрібні магічні номери, вимкнути макет та подібні речі. Коротке та елегантне рішення.

Я думаю, що весь код, пов'язаний з обмеженнями, повинен перейти до updateConstraintsметоду. Отже, давайте зробимо своє ResizableTextView.

Перша проблема, з якою ми зустрічаємось тут, полягає в тому, що не знаю реального розміру вмісту перед viewDidLoadметодом. Ми можемо пройти довгу і невдалу дорогу і обчислити її, виходячи з розміру шрифту, розривів рядків тощо. Але нам потрібно надійне рішення, тому ми зробимо:

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

Тож тепер ми знаємо справжній contentSize незалежно від того, де ми знаходимось: до чи після 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];
}

Гарненько і чисто, правда? І вам не доведеться мати справу з цим кодом у своїх контролерах !

Але зачекайте! Y НІ АНІМАЦІЇ!

Ви можете легко анімувати зміни, щоб зробити 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 пт прокладки з кожної сторони 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
Логіка

Закладка була ключовою для мене
thibaut noah

8

Ми можемо це зробити за допомогою обмежень.

  1. Встановити обмеження висоти для UITextView. введіть тут опис зображення

2.Створіть IBOutlet для обмеження висоти.

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

3. не забудьте встановити делегата для перегляду тексту.

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;
    }];

}

тоді оновіть обмеження так:


це прізвисько FANTASTIC!
Fattie

Визначення постійних потрібно дотримуватися [textView layoutIfNeeded]; у блоці анімації. (Анімації з автоматичним розкладом роблять це так.)
Буде Ларш

7

Наступних речей достатньо:

  1. Просто пам’ятайте, що для прокрутки увімкнено значення NO для вашого UITextView:

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

  1. Правильно встановити обмеження для автоматичної компонування.

Ви навіть можете використовувати UITableViewAutomaticDimension.


6

У поєднанні з відповіддю Майка Макмастера, можливо, ви захочете зробити щось на кшталт:

[myTextView setDelegate: self];

...

- (void)textViewDidChange:(UITextView *)textView {
  if (myTextView == textView) {
     // it changed.  Do resizing here.
  }
}

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];

Тут "5" в y - координаті UILabel є розривом, який я хочу між textView і Label.
dheeraj

6

Хлопці, які використовують авторозкладку, і ваш sizetofit не працює, тоді, будь ласка, перевіряйте обмеження ширини один раз. Якщо ви пропустили обмеження ширини, то висота буде точною.

Не потрібно використовувати будь-який інший API. лише один рядок вирішив би все питання.

[_textView sizeToFit];

Тут мене хвилювала лише висота, зберігаючи фіксовану ширину, і я пропустив обмеження ширини мого TextView у раскадровці.

І це мало показати динамічний контент від сервісів.

Сподіваюся, це може допомогти ..


6

Починаючи з iOS 8, можна використовувати функції автоматичного компонування UITableView для автоматичного зміни розміру UITextView без власного коду. Я поставив проект у github, який демонструє це в дії, але ось ключ:

  1. У UITextView повинно бути вимкнено прокрутку, що можна зробити програмно або через конструктор інтерфейсів. Він не змінить розмір, якщо прокрутка включена, оскільки прокрутка дозволяє переглядати більший вміст.
  2. У viewDidLoad для UITableViewController, необхідно встановити значення для estimatedRowHeight , а потім встановити 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відповідну конкретну область:

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

- (недійсна) reduFontToFit: (UITextView *) tv {
    UIFont * font = tv.font;
    подвійний pointSize = font.pointSize;

    while (tv.contentSize.height> tv.frame.size.height && pointSize> 7.0) {
        pointSize - = 1,0;
        UIFont * newFont = [UIFont fontWithName: font.fontName розмір: pointSize];
        tv.font = newFont;
    }
    якщо (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;
}

3

Для iOS 7.0, замість того, щоб встановити frame.size.heightзначення contentSize.height(що наразі нічого не робить) [textView sizeToFit].

Дивіться це питання .


2

Використання UITextViewDelegate - це найпростіший спосіб:

func textViewDidChange(_ textView: UITextView) {
    textView.sizeToFit()
    textviewHeight.constant = textView.contentSize.height
}

1

Сподіваюся, це допомагає:

- (void)textViewDidChange:(UITextView *)textView {
  CGSize textSize = textview.contentSize;
  if (textSize != textView.frame.size)
      textView.frame.size = textSize;
}

Це не працює! Це спричиняє помилку: "потрібне значення як лівий операнд призначення"
leviathan

Ви можете призначити лише textView.frame.
jweyrich

1

якщо будь-який інший потрапить сюди, це рішення працює для мене, 1 "Ronnie Liew" +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;

І це ... Будьте здорові


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 з автоматичним розгортанням:

    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
            }
        }
    }

1

Швидка відповідь: Наступний код обчислює висоту текстуView.

                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


Вибачте, що це означає: let attribute = [NSFontAttributeName: textView.text.font!] Це справді Swift-код без помилок?) Ви мали на увазі let attribute = [NSFontAttributeName: textView.font!]
Massmaker
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.