ios - scrollViewWillEndDragging: withVelocity: targetContentOffset: no funciona en los bordes de un UISCrollView
ios5 uiscrollviewdelegate (5)
Encontré 2 comportamientos indocumentados que puede investigar: - Establecer cero como el desplazamiento final no funciona, sugiero poner 1 o algo mayor que cero (0.5 puede funcionar, no probado) - Será mejor que compruebe el signo de velocidad y calcule su desplazamiento final para estar en el lado izquierdo o derecho del punto actual donde el usuario lo eliminó es el dedo. No intente hacer que el desplazamiento vaya hacia atrás en el otro lado.
Estoy tratando de implementar una barra de pestañas personalizada que es desplazable y tiene paginación en cada elemento de la barra de pestañas. Para eso estoy usando el delegado scrollViewWillEndDragging: withVelocity: targetContentOffset: que funciona perfectamente con un problema.
La forma en que funciona mi paginación es que, si contentOffset está cerca del elemento correcto, targetContentOffset cambia al desplazamiento de ese elemento. Lo mismo para el lado izquierdo.
El problema es que siempre que esté en la mitad izquierda del primer elemento y en el derecho del último (la vista de desplazamiento funciona horizontalmente) se supone que debe ir a ContentOffset 0 y el desplazamiento de contenido del elemento más a la derecha (menos los que están en pantalla), pero no lo hace.
Verifiqué con el depurador y targetContentOffset-> x es de hecho 0 (en el primer caso, a la izquierda del elemento que está más a la izquierda). Entonces el problema es que el UIScrollView no se desplaza allí. Estoy perdido.
Aquí está mi delegado implementado:
- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView
withVelocity:(CGPoint)velocity
targetContentOffset:(inout CGPoint *)targetContentOffset{
NSInteger index = lrintf(targetContentOffset->x/self.tabWidth);
targetContentOffset->x = index * self.tabWidth;
}
Aquí está el diagrama explicando lo que quiero hacer.
|-------|-------|-------|-------|-------|-------|-------|
| | | | | | | |
| | | | | | | |
|_______|_______|_______|_______|_______|_______|_______|
|_______________________________________|
where it is and i scroll it to the left
<----|
|_______________________________________|
where it would stop
|_______________________________________|
where i want it to stop
Este es un problema conocido que parece. Después de algunas investigaciones y hablar con otras personas, se sugirió que podría tratarse de un error, que resultó ser correcto. Lo reporté a Apple y estaba marcado como duplicado pero aún está abierto. Solo respondiendo para aquellos de ustedes con el mismo problema. Lo soluciono como sugiere Big Papoo, usando un desplazamiento cercano a lo que quiero (parece que 0.1 lo hace). Lo mismo para el extremo derecho.
Intenté establecer el desplazamiento final en un valor ligeramente inferior a cero o el tamaño del contenido sugerido por Big Papoo, pero noté que esto elimina el rebote sobre el desplazamiento. Mi solución a esto fue verificar el targetContentOffset original para ver si es igual a cero o contentSize y dejarlo si es:
- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset {
float expectedOffset = targetContentOffset->x;
if (expectedOffset == 0 || expectedOffset == scrollView.contentSize.width) return; // Scroll view will bounce so leave the targetContentOffset.
float targetOffset = [self roundedOffset:expectedOffset]; // Round your offset.
// Adjust the offset to make sure it works.
if (targetOffset == 0) targetOffset = 1;
else if (targetOffset == SCROLLVIEW_WIDTH) targetOffset = SCROLLVIEW_WIDTH - 1;
targetContentOffset->x = targetOffset;
}
Por supuesto, puede usar scrollViewDidEndDecelerating:
para mover la vista de desplazamiento en ese punto.
Problema solucionado en iOS 6.0.
Ahora funciona como debería.
Si está utilizando una vista de tabla horizontal, entonces dentro de su función scrollViewWillEndDragging: withVelocity: targetContentOffset: puede llamar a:
[self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:<index> inSection:<section>] atScrollPosition:UITableViewScrollPositionTop animated:YES];
Encontré que esto funciona mucho mejor que tratar de manipular targetContentOffset-> y en una vista de tabla horizontal.