UIScrollView ajusta contentOffset cuando cambia contentSize
Estoy ajustando el estado de un controlador de vista de detalle, justo antes de que se presione en un navigationController
:
[self.detailViewController detailsForObject:someObject];
[self.navigationController pushViewController:self.detailViewController
animated:YES];
En el DetailViewController
reside una vista de desplazamiento. Qué contenido redimensiono basado en el objeto pasado:
- (void)detailsForObject:(id)someObject {
// set some textView's content here
self.contentView.frame = <rect with new calculated size>;
self.scrollView.contentSize = self.contentView.frame.size;
self.scrollView.contentOffset = CGPointZero;
}
Ahora, todo esto funciona, pero el ScrollView ajusta su contentOffset
durante la animación de slide-in del NavigationController. El contentOffset
se establecerá a la diferencia entre el último contentSize y el nuevo calculado. Esto significa que la segunda vez que abra DetailsView, el los detalles se desplazarán a alguna ubicación no deseada. Aunque estoy configurando contentOffset
a CGPointZero
explícitamente.
Encontré que restablecer el contentOffset
en - viewWillAppear
no tiene ningún efecto. Lo mejor que se me ocurrió es restablecer el contentOffset en viewDidAppear
, causando un notable movimiento hacia arriba y hacia abajo del contenido:
- (void)viewDidAppear:(BOOL)animated {
self.scrollView.contentOffset = CGPointZero;
}
¿Hay alguna manera de evitar que un UIScrollView
ajuste su contentOffset
cuando se cambia su contentSize
?
7 answers
Ocurre cuando se empuja un UIViewController
que contiene un UIScrollView
usando un UINavigationController
.
IOS 7
Solución 1 (Código)
Conjunto @property(nonatomic, assign) BOOL automaticallyAdjustsScrollViewInsets
a NO
.
Solución 2 (Storyboard)
Desmarca el Adjust Scroll View Insets
IOS 6
Solución (Código)
Establece la propiedad UIScrollView
contentOffset
y contentInset
en viewWillLayoutSubviews
. Código de ejemplo:
- (void)viewWillLayoutSubviews{
[super viewWillLayoutSubviews];
self.scrollView.contentOffset = CGPointZero;
self.scrollView.contentInset = UIEdgeInsetsZero;
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-12-02 10:14:32
La causa de este problema sigue sin estar clara, aunque he encontrado una solución. Al restablecer el tamaño y el desplazamiento del contenido antes de ajustarlos, UIScrollView no se animará:
- (void)detailsForObject:(id)someObject {
// These 2 lines solve the issue:
self.scrollView.contentSize = CGSizeZero;
self.scrollView.contentOffset = CGPointZero;
// set some textView's content here
self.contentView.frame = <rect with new calculated size>;
self.scrollView.contentSize = self.contentView.frame.size;
self.scrollView.contentOffset = CGPointZero;
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-07-11 13:45:41
Tuve el mismo problema con un UIScrollView, donde el problema fue causado por no establecer el contentSize. Después de establecer el contentSize al número de elementos, este problema se resolvió.
self.headerScrollView.mainScrollview.contentSize = CGSizeMake(320 * self.sortedMaterial.count, 0);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-09-23 13:29:19
Esto es lo que funcionó para mí:
En el storyboard, en el Inspector de tamaño para ScrollView, establezca el comportamiento de ajuste de Inserciones de contenido en"Nunca".
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-07-13 20:54:52
¿Es su ScrollView la vista raíz del DetailViewController? Si es así, intente envolver la vista de desplazamiento en un UIView
simple y haga de esta última la vista raíz de DetailViewController. Dado que UIView
s no tienen una propiedad contentOffset
, son inmunes a los ajustes de desplazamiento de contenido realizados por el controlador de navegación (debido a la barra de navegación, etc.).).
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-06-29 16:21:38
Experimenté el problema, y para un caso específico - no ajusto el tamaño - utilicé lo siguiente:
float position = 100.0;//for example
SmallScroll.center = CGPointMake(position + SmallScroll.frame.size.width / 2.0, SmallScroll.center.y);
Lo mismo funcionaría con y: anotherPosition + SmallScroll.frame.size.height / 2.0
Así que si no necesita cambiar el tamaño, esta es una solución rápida e indolora.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-11-05 15:31:11
Estaba experimentando un problema similar, donde UIKit estaba configurando el contentOffset de mi ScrollView durante las animaciones push.
Ninguna de estas soluciones funcionaba para mí, tal vez porque estaba apoyando iOS 10 y iOS 11.
Pude solucionar mi problema mediante la subclase de mi scrollview para evitar que UIKit cambiara mis compensaciones después de que el scrollview se hubiera eliminado de la ventana:
/// A Scrollview that only allows the contentOffset to change while it is in the window hierarchy. This can keep UIKit from resetting the `contentOffset` during transitions, etc.
class LockingScrollView: UIScrollView {
override var contentOffset: CGPoint {
get {
return super.contentOffset
}
set {
if window != nil {
super.contentOffset = newValue
}
}
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-07-26 17:51:06