iOS7 UITextView contentsize.альтернатива высоты
Я портирую одно из приложений с iOS 6.1 на iOS 7. Я использую макет, где есть UITextView
Это имеет фиксированную ширину, но его высота основана на его contentsize. Для iOS 6.1 проверка contentsize.высота и установка его в качестве высоты кадра textview было достаточно, но он не работает на iOS 7.
Как я могу тогда создать UITextView
с фиксированной шириной, но динамической высотой на основе текста, который он показывает?
примечание: Я создаю эти представления из кода, а не с Конструктор Интерфейсов.
9 ответов:
С помощью этого кода Вы можете изменить высоту вашего UITextView в зависимости от фиксированной ширины (он работает на iOS 7 и предыдущей версии):
- (CGFloat)textViewHeightForAttributedText:(NSAttributedString *)text andWidth:(CGFloat)width { UITextView *textView = [[UITextView alloc] init]; [textView setAttributedText:text]; CGSize size = [textView sizeThatFits:CGSizeMake(width, FLT_MAX)]; return size.height; }
С помощью этой функции вы возьмете NSAttributedString и фиксированную ширину, чтобы вернуть необходимую высоту.
если вы хотите вычислить кадр из текста с определенным шрифтом, вам нужно использовать следующий код:
- (CGSize)text:(NSString *)text sizeWithFont:(UIFont *)font constrainedToSize:(CGSize)size { if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0")) { CGRect frame = [text boundingRectWithSize:size options:(NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading) attributes:@{NSFontAttributeName:font} context:nil]; return frame.size; } else { return [text sizeWithFont:font constrainedToSize:size]; } }
вы можете добавить, что
SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO
на ваш префикс.PCH файл в вашем проекте как:#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)
вы также можете заменить предыдущий тест
SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v)
by:if ([text respondsToSelector:@selector(boundingRectWithSize:options:attributes:context:)])
это сработало для меня для iOS6 и 7:
CGSize textViewSize = [self.myTextView sizeThatFits:CGSizeMake(self.myTextView.frame.size.width, FLT_MAX)]; self.myTextView.height = textViewSize.height;
в iOS7,
UITextView
используетNSLayoutManager
макет текста:// If YES, then the layout manager may perform glyph generation and layout for a given portion of the text, without having glyphs or layout for preceding portions. The default is NO. Turning this setting on will significantly alter which portions of the text will have glyph generation or layout performed when a given generation-causing method is invoked. It also gives significant performance benefits, especially for large documents. @property(NS_NONATOMIC_IOSONLY) BOOL allowsNonContiguousLayout;
отключить
allowsNonContiguousLayout
исправитьcontentSize
:textView.layoutManager.allowsNonContiguousLayout = NO;
используйте эту маленькую функцию
-(CGSize) getContentSize:(UITextView*) myTextView{ return [myTextView sizeThatFits:CGSizeMake(myTextView.frame.size.width, FLT_MAX)]; }
мое окончательное решение основано на HotJard, но включает в себя как верхние, так и нижние вставки текстового контейнера вместо использования 2*fabs(textView.contentInset.сверху) :
- (CGFloat)textViewHeight:(UITextView *)textView { return ceilf([textView.layoutManager usedRectForTextContainer:textView.textContainer].size.height + textView.textContainerInset.top + textView.textContainerInset.bottom); }
есть более простое решение, используя этот метод:
+(void)adjustTextViewHeightToContent:(UITextView *)textView; { if([[UIDevice currentDevice].systemVersion floatValue] >= 7.0f){ textView.height = [textView.layoutManager usedRectForTextContainer:textView.textContainer].size.height+2*fabs(textView.contentInset.top); }else{ textView.height = textView.contentSize.height; } }
UPD: работает только для отображения текста (isEditable = NO)
_textView.textContainerInset = UIEdgeInsetsZero; _textView.textContainer.lineFragmentPadding = 0;
просто не забудьте lineFragmentPadding
простое решение -
textView.isScrollEnabled = false
отлично работает, когда внутри другого вида прокрутки или ячейки tableView сUITableViewAutomaticDimension
@Ana's, @ Blake Hamilton решение в Свифт.
var contentHeight: CGFloat = textView.sizeThatFits(textView.frame.size).height
хорошая вещь для меня было то, что это также возвращает правильный
contentSize
, когдаisScrollEnable
имеет значение false. Значение false возвращает размер кадра текстового представления вместо размера содержимого.