Te daré mi solución, pero como todo es bastante grande, Solo te daré los fragmentos relevantes.
Además, tenga en cuenta que utilizo un reconocedor de gestos para el arrastre (UILongPressGestureRecognizer) ya que así es como el usuario inicia el arrastre en mi aplicación, manteniendo su dedo presionado sobre el objeto. Por lo tanto, cada subvista que puede arrastrar tiene su propio UILongPressGestureRecognizer asignado, y el destino/selector de ese reconocedor está en otra clase que administra tanto la vista de desplazamiento como las subvistas.
aquí es el objetivo del reconocedor gesto:
-(void)dragged:(UILongPressGestureRecognizer *)panRecog
{
if (panRecog.state == UIGestureRecognizerStateBegan)
{
UIView * pannedView = panRecog.view;
dragView = pannedView;
dragView.center = [panRecog locationInView:scrollView];
[scrollView bringSubviewToFront:dragView];
[self startDrag]; // Not important, changes some stuff on screen to show the user he is dragging
return;
}
if (panRecog.state == UIGestureRecognizerStateChanged)
{
int xDelta = dragView.center.x - [panRecog locationInView:scrollView].x;
dragView.center = [panRecog locationInView:scrollView];
[self scrollIfNeeded:[panRecog locationInView:scrollView.superview] withDelta:xDelta];
return;
}
if (panRecog.state == UIGestureRecognizerStateEnded)
{
[self endDrag]; // Not important, changes some stuff on screen to show the user he is not dragging anymore
}
}
las cosas que son relevantes para usted:
- Al iniciar el arrastre almaceno la vista que me arrastre en dragView y establecer su centro para ser la posición de su dedo en relación con la vista de desplazamiento en la que se encuentra.
- startDrag no es importante para usted, cambia algunas cosas en la pantalla para mostrar al usuario que está arrastrando
- Cuando realmente movemos nuestro objeto (UIGestureRecognizerStateChanged) obtengo la cantidad de puntos que el usuario movió su dedo y uso ese delta junto con la posición del dedo del usuario para verificar si la vista de desplazamiento debe moverse en scrollSi se necesita.
Este es el código
-(void)scrollIfNeeded:(CGPoint)locationInScrollSuperview withDelta:(int)xDelta
{
UIView * scrollSuperview = scrollView.superview;
CGRect bounds = scrollSuperview.bounds;
CGPoint scrollOffset = scrollView.contentOffset;
int xOfs = 0;
int speed = 10;
if ((locationInScrollSuperview.x > bounds.size.width * 0.7) && (xDelta < 0))
{
xOfs = speed * locationInScrollSuperview.x/bounds.size.width;
}
if ((locationInScrollSuperview.x < bounds.size.width * 0.3) && (xDelta > 0))
{
xOfs = -speed * (1.0f - locationInScrollSuperview.x/bounds.size.width);
}
if (xOfs < 0)
{
if (scrollOffset.x == 0) return;
if (xOfs < -scrollOffset.x) xOfs = -scrollOffset.x;
}
scrollOffset.x += xOfs;
CGRect rect = CGRectMake(scrollOffset.x, 0, scrollView.bounds.size.width, scrollView.bounds.size.height);
[scrollView scrollRectToVisible:rect animated:NO];
CGPoint center = dragView.center;
center.x += xOfs;
dragView.center=center;
}
Esta cosa sólo el desplazamiento horizontal, vertical, pero el manejo sería bastante similar. Lo que hace es:
- Compruebe que ha arrastrado en la región límite de la ScrollView (utilizo una frontera 30% a izquierda y derecha como la zona donde el desplazamiento debe suceder). Pero solo si el usuario se movió en esa dirección (xDelta < 0 para izquierda, xDelta> 0 para derecha)
- siguiente Calculo cuánto mover la vista de desplazamiento, usando una constante de velocidad y escalando esto con qué distancia está el usuario del borde real de la vista de desplazamiento, por lo que la velocidad es proporcional a la distancia al borde del usuario.
- El último paso es desplazar la vista de desplazamiento con un scrollRectToVisible no animado. Por supuesto, su vista arrastrada se mueve, por lo que compensamos eso con un desplazamiento opuesto de su centro.
Espero que esto pueda ayudarlo.
¡Eso es lo que necesito! Realmente gracias – ultragtx
Bien hecho, gracias;)! – Oliver
¡Esto funciona genial! Sin embargo, su calculo de xDelta debe ser la ubicación actual menos la última ubicación. valor final menos valor inicial, de modo que un usuario positivo xDelta menos arrastrado a la derecha, y xDelta negativo significa que arrastró a la izquierda. pero también funciona a tu manera. :) – ucangetit