2011-02-09 9 views
39

Implementé con éxito un pellizco un zoom de una vista. Sin embargo, la vista no se ubica donde yo deseaba. Para los stackoverflowers con un iPad, me gustaría que mi vista se centre como en el iPad Photos.app: cuando pellizcas & acercas un álbum, las fotos se muestran en una vista que se está expandiendo. Esta vista se centra aproximadamente con la esquina superior derecha en el primer dedo y el dedo inferior izquierdo en el otro dedo. Lo mezclé con un reconocedor de sartenes, pero de esta manera el usuario siempre tiene que pellizcar, y luego hacer una panorámica para ajustar.UIPinchGestureRecognizer posición de la vista pellizcada entre los dos dedos

Éstos son la explicación de modo gráfico, que podría publicar un video de mi aplicación si eso es poco claro (no es un secreto, que estoy tratando de reproducir el Photos.app del iPad ...)

Así que para una inicial posición de los dedos, el comenzar de zoom:

enter image description here

Este es el marco de "zoom" real por ahora. La plaza es grande, pero la posición está por debajo de los dedos

given the start position

Esto es lo que me gustaría tener: mismo tamaño, pero diferente origin.x e Y:

enter image description here

(perdón por mis pobres habilidades de photoshop ^^)

+0

HI Thomas, también estoy muy interesado en eso. ¿Encontraste alguna solución al respecto? ¿Tienes algún código de muestras? thx ~ – ludo

+2

No he tenido tiempo de volver a este tema, pero la respuesta de @md_develop se ve muy bien. Trataré de encontrar algo de tiempo para actualizar mi código y aceptar la respuesta si esto funciona –

Respuesta

41

que pueda obtener el CGPoint del punto medio entre dos dedos a través del código siguiente en el método handlingPinchGesture.

CGPoint point = [sender locationInView:self]; 

Todo mi método es handlePinchGesture a continuación.

/* 
instance variables 

CGFloat lastScale; 
CGPoint lastPoint; 
*/ 

- (void)handlePinchGesture:(UIPinchGestureRecognizer *)sender { 
    if ([sender numberOfTouches] < 2) 
     return; 

    if (sender.state == UIGestureRecognizerStateBegan) { 
     lastScale = 1.0; 
     lastPoint = [sender locationInView:self]; 
    } 

    // Scale 
    CGFloat scale = 1.0 - (lastScale - sender.scale); 
    [self.layer setAffineTransform: 
     CGAffineTransformScale([self.layer affineTransform], 
           scale, 
           scale)]; 
    lastScale = sender.scale; 

    // Translate 
    CGPoint point = [sender locationInView:self]; 
    [self.layer setAffineTransform: 
     CGAffineTransformTranslate([self.layer affineTransform], 
            point.x - lastPoint.x, 
            point.y - lastPoint.y)]; 
    lastPoint = [sender locationInView:self]; 
} 
+1

¿cómo podría funcionar esto cuando [remitente locationInView: self] siempre devuelve el mismo punto, el punto medio entre los dos dedos que pellizcan? – Guy

+1

@El punto medio de la letra está cambiando después de 'UIGestureRecognizerStateBegan' porque mueve los dedos lejos o más cerca. 'locationInView: self' devuelve centroide entre dos dedos. Esa parte funciona Aunque después de 1 hora todavía no puedo hacer que funcione en mi aplicación, donde tengo un montón de capas que necesito mover. –

+1

Utilicé este método y la vista se tradujo correctamente. Sin embargo, la forma en que se traduce no es tan fluida como la aplicación de fotos –

11

Eche un vistazo a Touches sample project. Específicamente estos métodos podrían ayudarle a:

// scale and rotation transforms are applied relative to the layer's anchor point 
// this method moves a gesture recognizer's view's anchor point between the user's fingers 
- (void)adjustAnchorPointForGestureRecognizer:(UIGestureRecognizer *)gestureRecognizer { 
    if (gestureRecognizer.state == UIGestureRecognizerStateBegan) { 
     UIView *piece = gestureRecognizer.view; 
     CGPoint locationInView = [gestureRecognizer locationInView:piece]; 
     CGPoint locationInSuperview = [gestureRecognizer locationInView:piece.superview]; 

     piece.layer.anchorPoint = CGPointMake(locationInView.x/piece.bounds.size.width, locationInView.y/piece.bounds.size.height); 
     piece.center = locationInSuperview; 
    } 
} 

// scale the piece by the current scale 
// reset the gesture recognizer's rotation to 0 after applying so the next callback is a delta from the current scale 
- (void)scalePiece:(UIPinchGestureRecognizer *)gestureRecognizer 
{ 
    [self adjustAnchorPointForGestureRecognizer:gestureRecognizer]; 

    if ([gestureRecognizer state] == UIGestureRecognizerStateBegan || [gestureRecognizer state] == UIGestureRecognizerStateChanged) { 
     [gestureRecognizer view].transform = CGAffineTransformScale([[gestureRecognizer view] transform], [gestureRecognizer scale], [gestureRecognizer scale]); 
     [gestureRecognizer setScale:1]; 
    } 
} 
+0

gracias, pero usar 'view.transform' cambia el tamaño de mis subvistas también ... ¿Hay alguna manera de evitar eso? –

+0

#import - Lo necesitaba para el anclaPoint –

Cuestiones relacionadas