doesn ios uiscrollview autolayout

ios - doesn - scrollview xcode



UIScrollView offset incorrecto con diseño automático (7)

Agregue una propiedad global contentOffset y guarde el contentOffset actual en viewDidDisappear. Una vez que regrese, se llamará al método viewDidLayoutSubviews y podrá configurar su contentOffset original.

- (void)viewDidLayoutSubviews { [super viewDidLayoutSubviews]; [self.scrollView setContentOffset:self.contentOffset animated:FALSE]; } - (void)viewDidDisappear:(BOOL)animated { [super viewDidDisappear:animated]; self.contentOffset = self.scrollView.contentOffset; [self.scrollView setContentOffset:CGPointMake(0, 0) animated:FALSE]; }

Tengo una configuración de vista bastante simple:

Un UIViewController , con un niño UIScrollView y un UIImageView en este UIScrollView . Configuré el UIImageView con una altura suficiente para salir del área visible (es decir, más alta a 1024pt ), y configuré el Bottom space to superview restricción de mi UIImageView a un valor positivo fijo ( 20 por ejemplo).

Toda la configuración funciona como se esperaba, la imagen se desplaza muy bien en su elemento principal. Excepto cuando la vista se desplaza (el efecto es más visible si se desplazó hasta la parte inferior de la vista), luego desaparece y vuelve a aparecer (cambió a otra vista y regresó) se restaura el valor de desplazamiento, pero el contenido del la vista de desplazamiento se mueve a la parte superior exterior de su vista principal.

Esto no es simple de explicar, intentaré dibujarlo:

Si desea probar / ver la fuente (o el guión gráfico, no edité una sola línea de código). Puse una pequeña demostración en mi github: https://github.com/guillaume-algis/iOSAutoLayoutScrollView

Leí el registro de cambios de iOS 6 y la explicación sobre este tema en particular, y creo que esta es la implementación correcta de la segunda opción (diseño automático puro), pero en este caso, ¿por qué el comportamiento de UIScrollView tan irregular? Me estoy perdiendo de algo ?

EDITAR : Este es el mismo problema que el # 12580434 uiscrollview-autolayout-issue . Las respuestas son solo soluciones, ya que cualquier persona encontró una forma adecuada de solucionar esto o ¿es esto un error de iOS?

EDIT 2 : Encontré otra solución, que mantiene la posición de desplazamiento en el mismo estado que el usuario dejó (esto es una mejora sobre la respuesta aceptada de 12580434 ):

@interface GAViewController () @property CGPoint tempContentOffset; @end @implementation GAViewController -(void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; self.tempContentOffset = self.mainScrollView.contentOffset; self.scrollView.contentOffset = CGPointZero; } -(void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; self.scrollView.contentOffset = self.tempContentOffset; }

Básicamente, guarde el desplazamiento en viewWillAppear , reinícielo al origen y luego restaure el valor en viewDidAppear . El problema parece ocurrir entre estas dos llamadas, pero no puedo encontrar su origen.


La edición no funcionó para mí. Pero esto funcionó:

-(void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; self.tempContentOffset = self.scrollView.contentOffset; self.scrollView.contentOffset = CGPointZero; } - (void)viewDidLayoutSubviews { [super viewDidLayoutSubviews]; self.scrollView.contentOffset = self.tempContentOffset; }


Para mí fui al IB, hice clic en mi controlador de vista que contiene la vista de desplazamiento. Luego fui a Attribute Inspector -> View Controller -> Extend Edges -> Desmarque "Under Top Bars" y "Under Bottom Bars".


Parece que el problema se resolvió con el dispatch_async durante la vista viewWillAppear:

- (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; CGPoint originalContentOffset = self.scrollView.contentOffset; self.scrollView.contentOffset = CGPointZero; dispatch_async(dispatch_get_main_queue(), ^{ self.scrollView.contentOffset = originalContentOffset; }); }


Sí, algo extraño sucedió con UIScrollView en el entorno de autodiseño puro. Al volver a leer las notas de la versión iOS SDK 6.0 por vigésima vez, descubrí que:

Tenga en cuenta que puede hacer que una subvista de la vista de desplazamiento parezca flotar (no desplazarse) sobre el otro contenido de desplazamiento creando restricciones entre la vista y una vista fuera del subárbol de la vista de desplazamiento, como la supervista de la vista de desplazamiento.

Solución

Conecte su subvista a la vista exterior. En otras palabras, a la vista en la que scrollview está incrustada.

Como IB no nos permite establecer restricciones entre el imageView y una vista fuera del subárbol de la vista de desplazamiento, como la supervista de la vista de desplazamiento, entonces lo he hecho en código.

- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. [self.view removeConstraints:[self.view constraints]]; [self.scrollView removeConstraints:[self.scrollView constraints]]; [self.imageView removeConstraints:[self.imageView constraints]]; [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"|[_scrollView]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(_scrollView)]]; [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[_scrollView]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(_scrollView)]]; [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"|[_imageView(700)]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(_imageView)]]; [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[_imageView(1500)]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(_imageView)]]; }

Y vau! ¡Funciona!


Solución simple encontrada, solo pon

[self setAutomaticallyAdjustsScrollViewInsets:NO];

en el método viewDidLoad de ViewControllers

- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view from its nib. [self setAutomaticallyAdjustsScrollViewInsets:NO]; }


Tuve un problema similar al usar UIScrollView en un UIViewController con un espacio extra superior que no era visible en Storyboard. La solución para mí fue quitar la marca de "Ajustar las configuraciones de la vista de desplazamiento" en las propiedades del guión gráfico de ViewController: ver respuesta Espacio extra (recuadro) en la vista de desplazamiento en tiempo de ejecución