ios uitextview ios7

iOS7 UITextView contentsize.height alternativa



(8)

Voy a portar una de las aplicaciones de iOS 6.1 a iOS 7. Estoy usando un diseño donde hay una UITextView que tiene un ancho de corrección, pero su altura se basa en su contenido. Para iOS 6.1 comprobar el contenido.height y configurarlo como la altura del marco de la vista de texto era suficiente, pero no funciona en iOS 7.

¿Cómo puedo crear un UITextView con un ancho fijo, pero con una altura dinámica basada en el texto que se muestra?

NOTA: Estoy creando estas vistas desde el código, no con el Interface Builder.


Con este código siguiente, puede cambiar la altura de su UITextView dependiendo de un ancho fijo (funciona en iOS 7 y en la versión anterior):

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

Con esta función, tomará un NSAttributedString y un ancho fijo para devolver la altura necesaria.

Si desea calcular el marco de un texto con una fuente específica, debe usar el siguiente código:

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

Puede agregar ese SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO en su archivo prefix.pch en su proyecto como:

#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)

También puede reemplazar la prueba anterior SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) por:

if ([text respondsToSelector:@selector(boundingRectWithSize:options:attributes:context:)])‌


En iOS7, UITextView usa NSLayoutManager para diseñar texto:

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

deshabilitar allowsNonContiguousLayout para reparar contentSize :

textView.layoutManager.allowsNonContiguousLayout = NO;


Esto funcionó para mí para iOS6 y 7:

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


Hay una solución más simple, usando este método:

+(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 : funciona solo para mostrar texto (isEditable = NO)


Mi solución final está basada en HotJard, pero incluye inserciones de texto superior e inferior en lugar de usar 2 * fabs (textView.contentInset.top):

- (CGFloat)textViewHeight:(UITextView *)textView { return ceilf([textView.layoutManager usedRectForTextContainer:textView.textContainer].size.height + textView.textContainerInset.top + textView.textContainerInset.bottom); }


Usa esta pequeña función

-(CGSize) getContentSize:(UITextView*) myTextView{ return [myTextView sizeThatFits:CGSizeMake(myTextView.frame.size.width, FLT_MAX)]; }


solución simple - textView.isScrollEnabled = false funciona perfecto cuando está dentro de otra vista de desplazamiento, o celda UITableViewAutomaticDimension con UITableViewAutomaticDimension


_textView.textContainerInset = UIEdgeInsetsZero; _textView.textContainer.lineFragmentPadding = 0;

No olvides el lineFragmentPadding