UITextView cambiando visualmente la position del contenido al pegar en text

Tengo una UITextView que está diseñada para ampliarse para adaptarse a la ContentView cuando sea necesario. Sin embargo, cuando pego un párrafo de text, coloca los puntos de inicio y fin del contenido verticalmente en lugares incorrectos. Al ingresar o eliminar un personaje, vuelve a colocarlo en la position correcta.

¿Alguna idea de por qué es esto?

-(void)textViewDidChange:(UITextView *)textView { self.textView.frame = CGRectMake( self.textView.frame.origin.x, self.textView.frame.origin.y, self.textView.frame.size.width, self.textView.contentSize.height + HEADER_ADDITIONAL_HEIGHT); self.textView.contentOffset = CGPointMake(0, 0); self.previousContentSize = textView.contentSize; } 

Cuando utilicé:

 textView.contentSize = textView.frame.size; textView.contentOffset = CGPointZero; 

Resolvió mi problema, pero creó un nuevo problema en el que a veces obtenemos un desplazamiento extraño al escribir o eliminar text. Entonces, utilicé esto:

 textView.contentSize = CGSizeMake( textView.contentSize.width, textView.contentSize.height+1); 

Esto también resolvió el problema. Creo que lo que todos necesitamos aquí es el efecto que obtenemos cuando se cambia el contentSize Tamaño de una vista de text. Desafortunadamente, no sé cuál es este efecto. Si alguien lo sabe, por favor díselo.

Actualización: encontré un método que puede usar para resolver su problema (lo usé para resolver el mío). Puede solicitar a NSLayoutMAnager que actualice todo el layout:

 [textView.textStorage edited:NSTextStorageEditedCharacters range:NSMakeRange(0, textView.textStorage.length) changeInLength:0]; 

NSLayoutManager intenta evitar actualizar el layout porque lleva mucho time y requiere mucho trabajo, por lo que está configurado para hacerlo solo cuando sea absolutamente necesario (perezoso). Hay una serie de funciones invalidateLayout relacionadas con esta class, pero ninguna de ellas provoca una nueva disposition cuando se llama.

Sé que esto llega tarde, pero me encontré con este problema y pensé que debería compartir lo que se me ocurrió en caso de que otros se encuentren en la misma situación.

Estás en el path correcto, pero en textViewDidChange: te falta una cosa importante: establecer el contenidoSize después de actualizar la altura del marco.

 // I used 0.f for the height, but you can use another value because according to the docs: // "the actual bounding rectangle returned by this method can be larger // than the constraints if additional space is needed to render the entire // string. Typically, the renderer preserves the width constraint and // adjusts the height constraint as needed." CGSize size = CGSizeMake(textview.frame.size.width, 0.f); CGRect rect = [string boundingRectWithSize:size options:OptionsYouNeedIfAny // NSStringDrawingOptions context:nil]; // Where MinTextViewHeight is the smallest height for a textView that // your design can handle CGFloat height = MAX(ceilf(rect.size.height), MinTextViewHeight); CGRect rect = textView.frame; rect.size.height = height; textView.frame = rect; // Adjusting the textView contentSize after updating the frame height is one of the things you were missing textView.contentSize = textView.frame.size; textView.contentOffset = CGPointZero; 

¡Espero que esto ayude!

Consulte los documentos para get más información sobre el uso de boundingRectWithSize:options:context: