Pregunta iOS7 UITextView contentsize.height alternativa


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


73
2017-09-26 12:48


origen


Respuestas:


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

Puedes agregar eso 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 puedes reemplazar la prueba anterior SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) por:

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

177
2017-09-28 13:25



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;

42
2017-10-09 13:19



En iOS7, UITextView usos NSLayoutManager al texto de diseño:

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

inhabilitar allowsNonContiguousLayout arreglar contentSize :

textView.layoutManager.allowsNonContiguousLayout = NO;

20
2018-02-27 11:02



Usa esta pequeña función

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

15
2017-10-13 00:37



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

3
2017-10-07 10:01



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


2
2017-10-02 13:00



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

No olvides el lineFragmentPadding


1
2017-08-08 03:25



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


0
2017-11-28 10:37