ios autolayout uitextview

ios - UITextView no se desplaza hacia arriba cuando se carga



autolayout (8)

El problema de poner código en viewDidLayoutSubviews y viewWillLayoutSubviews es que estos métodos se llaman mucho (durante la rotación del dispositivo, el cambio de tamaño de las vistas, etc.). Si está leyendo algo de la vista de texto y gira el dispositivo, espera que la parte del contenido que está viendo permanezca en la pantalla. No esperas que se desplace hacia atrás. En lugar de desplazar el contenido hacia arriba, intente mantener la propiedad scrollEnabled de la vista de texto establecida en NO (false) y vuelva a activarla en viewDidAppear.

Cuando tengo texto que no llena el UITextView, se desplaza hacia arriba para funcionar como se esperaba. Cuando hay más texto del que cabe en la pantalla, el UITextView se desplaza hacia la mitad del texto, en lugar de hacia la parte superior.

Aquí hay algunos detalles potencialmente relevantes:

En viewDidLoad para dar algo de relleno en la parte superior e inferior de UITextView:

self.mainTextView.textContainerInset = UIEdgeInsetsMake(90, 0, 70, 0);

El UITextView usa el diseño automático para anclarlo 20px desde la parte superior, inferior y cada lado de la pantalla (hecho en IB) para permitir diferentes tamaños de pantalla y orientaciones.

Todavía puedo desplazarlo con mi dedo una vez que esté cargado.

EDITAR Encontré que eliminar las restricciones de diseño automático y luego arreglar el ancho solo parece solucionar el problema, pero solo para ese ancho de pantalla.


Este es un error interesante. En nuestro proyecto, esto solo ocurre en dispositivos con una pantalla de tamaño de iPhone 5 . Parece que la vista de texto contentOffset cambia en algún momento durante el ciclo de vida del controlador de vista. En viewDidLoad y viewWillAppear el contentOffset de contentOffset es 0,0 , y por viewDidAppear ha cambiado. Puede verlo sucediendo en viewWillLayoutSubviews . Las restricciones parecen estar configuradas correctamente.

Esto garantizará que no llame a un método de desplazamiento a menos que sea necesario:

if textView.contentOffset.y > 0 { textView.contentOffset = CGPoint(x: 0, y: 0) // Or use scrollRectToVisible, scrollRangeToVisible, etc. }


Para iOS9 y versiones posteriores, la vista de texto incluso en viewWillAppear: viene con CGRect (0,0,1000,1000). Para que esto funcione, debe llamar a viewWillAppear:

[self.view setNeedsLayout]; [self.view layoutIfNeeded]; // * Your code here

Después de eso, la vista de texto tendrá los datos correctos de CGRect y podrá realizar cualquier operación de desplazamiento que pueda necesitar.


UITextView es una subclase de UIScrollView, por lo que puede usar sus métodos. Si todo lo que quiere hacer es asegurarse de que esté desplazado hacia la parte superior, entonces, dondequiera que se agregue el texto, intente:

[self.mainTextView setContentOffset:CGPointZero animated:NO];

EDITAR: AutoLayout con cualquier tipo de vista de desplazamiento se pone rápido. Ese ajuste de un ancho fijo lo resuelve no es sorprendente. Si no funciona en -viewDidLayoutSubviews entonces eso es impar. Establecer una restricción de diseño manualmente puede funcionar. Primero crea las restricciones en IB:

@property (weak, nonatomic) IBOutlet NSLayoutConstraint *textViewWidthConstraint; @property (weak, nonatomic) IBOutlet NSLayoutConstraint *textViewHeightConstraint;

luego en ViewController

-(void)updateViewConstraints { self.textViewWidthConstraint.constant = self.view.frame.size.width - 40.0f; self.textViewHeightConstraint.constant = self.view.frame.size.height - 40.0f; [super updateViewConstraints]; }

Todavía puede ser necesario configurar SetContentOffset en -viewDidLayoutSubviews .

(Otro método sería crear una restricción de diseño para "anchos iguales" e "alturas iguales" entre textView y su supervista, con una constante de "-40". Solo es "igual" si la constante es cero de lo contrario, se ajusta según la constante. Sin embargo, como solo puede agregar esta restricción a una vista que restringe ambas vistas, no puede hacer esto en IB.

Usted puede preguntarse, si tengo que hacer esto, ¿cuál es el objetivo de AutoLayout? He estudiado AutoLayout en profundidad, y esa es una excelente pregunta.


agregue la siguiente función a su clase de controlador de vista ...

Swift 3

override func viewDidLayoutSubviews() { self.mainTextView.setContentOffset(.zero, animated: false) }

Swift 2.1

override func viewDidLayoutSubviews() { self.mainTextView.setContentOffset(CGPointZero, animated: false) }

C objetivo

- (void)viewDidLayoutSubviews { [self.mainTextView setContentOffset:CGPointZero animated:NO]; }


tuve el mismo problema! Restablezca las restricciones sugeridas y simplemente ponga (y offset)

@IBOutlet weak var textContent: UITextView! override func viewDidLoad() { textContent.scrollsToTop = true var contentHeight = textContent.contentSize.height var offSet = textContent.contentOffset.x var contentOffset = contentHeight - offSet textContent.contentOffset = CGPointMake(0, -contentOffset) }


Rápido

self.textView.scrollRangeToVisible(NSMakeRange(0, 0))

C objetivo

[self.textView scrollRangeToVisible:(NSMakeRange(0, 0))];


Si no quieres meterse con restricciones:

override func updateViewConstraints() { super.updateViewConstraints() } override func viewDidLayoutSubviews() { self.textLabel.setContentOffset(CGPointZero, animated: false) }