2011-05-18 6 views
6

Estoy desarrollando una aplicación para iOS 4.2, iPhone, en esta aplicación descargo imágenes y las guardo en el almacenamiento interno (NSDocuments).¿Cómo puedo acercar y alejar un UIImageView sin UIScrollView?

Bueno, entonces muestro la primera imagen en un UIImageView. El usuario puede arrastrar el dedo sobre UIImageView (TouchesMoved), cuando el usuario hace eso, cargo otra imagen. Si el usuario arrastra hacia abajo, cargo una imagen, si la arrastro, cargo otra, y también con la derecha y la izquierda.

Todo listo. Pero quiero implementar el zoom. Este es mi código hasta ahora:

initialDistance -> es la distancia entre los dedos al primer toque
finalDistance -> es la distancia entre los dedos cada vez que se mueven
x -> 0 se
y -> es 0

// this method calculate the distance between 2 fingers 
    - (CGFloat)distanceBetweenTwoPoints:(CGPoint)fromPoint toPoint:(CGPoint)toPoint { 
     float xPoint = toPoint.x - fromPoint.x; 
     float yPoint = toPoint.y - fromPoint.y; 

     return sqrt(xPoint * xPoint + yPoint * yPoint); 
    } 

     //------------------- Movimientos con los dedos ------------------------------------ 
     #pragma mark - 
     #pragma mark UIResponder 

      // First Touch 
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{ 

NSSet *allTouches = [event allTouches]; 

switch ([allTouches count]) { 
    case 1: { //Single touch 

     //Get the first touch. 
     UITouch *touch1 = [[allTouches allObjects] objectAtIndex:0]; 

     switch ([touch1 tapCount]) 
     { 
      case 1: //Single Tap. 
      { 
       // Guardo la primera localización del dedo cuando pulsa por primera vez 
       //inicial = [touch1 locationInView:self.view]; 

      } break; 
      case 2: {//Double tap. 
       //Track the initial distance between two fingers. 
       //if ([[allTouches allObjects] count] >= 2) { 

       // oculto/o no, la barra de arriba cuando se hace un dobleTap 
       //[self switchToolBar]; 

      } break; 
     } 
    } break; 
    case 2: { //Double Touch 

     // calculo la distancia inicial que hay entre los dedos cuando empieza a tocar 
     UITouch *touch1 = [[allTouches allObjects] objectAtIndex:0]; 
     UITouch *touch2 = [[allTouches allObjects] objectAtIndex:1]; 

     initialDistance = [self distanceBetweenTwoPoints:[touch1 locationInView:[self view]] 
               toPoint:[touch2 locationInView:[self view]]]; 
    } 
    default: 
     break; 
} 
} 

// when the finger/s move to 
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event 
{ 

NSSet *allTouches = [event allTouches]; 

switch ([allTouches count]) 
{ 
    case 1: { 



    } break; 
    case 2: { 
     //The image is being zoomed in or out. 

     UITouch *touch1 = [[allTouches allObjects] objectAtIndex:0]; 
     UITouch *touch2 = [[allTouches allObjects] objectAtIndex:1]; 

     //Calculate the distance between the two fingers. 
     CGFloat finalDistance = [self distanceBetweenTwoPoints:[touch1 locationInView:[self view]] 
                 toPoint:[touch2 locationInView:[self view]]]; 

     NSLog(@"Distancia Inicial :: %.f, Ditancia final :: %.f", initialDistance, finalDistance); 

     float factorX = 20.0; 
     float factorY = 11.0; 

     // guardo la posicion de los 2 dedos 
     //CGPoint dedo1 = [[[touches allObjects] objectAtIndex:0] locationInView:self.view]; 
     //CGPoint dedo2 = [[[touches allObjects] objectAtIndex:1] locationInView:self.view]; 

     // comparo para saber si el usuario esta haciendo zoom in o zoom out 
     if(initialDistance < finalDistance) { 
      NSLog(@"Zoom In"); 

      float newWidth = imagen.frame.size.width + (initialDistance - finalDistance + factorX); 
      float newHeight = imagen.frame.size.height + (initialDistance - finalDistance + factorY); 

      if (newWidth <= 960 && newHeight <= 640) { 
       /* 
       if (dedo1.x >= dedo2.x) { 
       x = (dedo1.x + finalDistance/2); 
       y = (dedo1.y + finalDistance/2); 
       } else { 
       x = (dedo2.x + finalDistance/2); 
       y = (dedo2.y + finalDistance/2); 
       } 
       */ 

       //x = (dedo1.x); 
       //y = (dedo1.y); 

       imagen.frame = CGRectMake(x, y, newWidth, newHeight); 
      } else { 
       imagen.frame = CGRectMake(x, y, 960, 640); 
      } 



     } 
     else { 
      NSLog(@"Zoom Out"); 

      float newWidth = imagen.frame.size.width - (finalDistance - initialDistance + factorX); 
      float newHeight = imagen.frame.size.height - (finalDistance - initialDistance + factorY); 

      if (newWidth >= 480 && newHeight >= 320) { 
       /* 
       if (dedo1.x >= dedo2.x) { 
       x = (dedo1.x + finalDistance/2); 
       y = (dedo1.y + finalDistance/2); 
       } else { 
       x = (dedo2.x + finalDistance/2); 
       y = (dedo2.y + finalDistance/2); 
       } 
       */ 
       //x -= (finalDistance - initialDistance + factorX); 
       //y -= (finalDistance - initialDistance + factorX); 

       //x = (dedo1.x); 
       //y = (dedo1.y); 

       imagen.frame = CGRectMake(x, y, newWidth, newHeight); 
      } else { 
       imagen.frame = CGRectMake(0, 0, 480, 320); 
      } 



     } 

     initialDistance = finalDistance; 

    } break; 
} 
} 

#pragma mark - 

Muchas gracias !!

PD: Si hay un método con UIScrollView en el que puedo moverme entre diferentes imágenes, estoy abierto para echar un vistazo también.

+0

Si tiene la intención de utilizar eventos de arrastre/desplazamiento para pasar a la siguiente imagen, ¿cómo va a navegar el usuario por una imagen ampliada? –

+0

Él solo puede hacer zoom, no navegar. –

Respuesta

21

Ok. Puede considerar usar UIScrollView solo para usarlo para su funcionalidad de zoom.

Digamos que tenemos un scrollView y un imageView con ambos con los mismos límites. Agregue el imageView como la subvista de scrollView.

[scrollView addSubview:imageView]; 
scrollView.contentSize = imageView.frame.size; 

para admitir sólo el zoom y paneo no no en el scrollView su viewController tendrá que adoptar el protocolo UIScrollViewDelegate.

// Disabling panning/scrolling in the scrollView 
scrollView.scrollEnabled = NO; 

// For supporting zoom, 
scrollView.minimumZoomScale = 0.5; 
scrollView.maximumZoomScale = 2.0; 

... 

// Implement a single scroll view delegate method 
- (UIView*)viewForZoomingInScrollView:(UIScrollView *)aScrollView { 
    return imageView; 
} 

Por ahora tenemos zoom disponible. Para los golpes, puede usar el UISwipeGestureRecognizers configurado correctamente. Cree un gesto para manejar cada dirección de deslizamiento y agréguelo a la vista de desplazamiento.

UISwipeGestureRecognizer *rightSwipe = [[UISwipeGestureRecognizer alloc] initWithTarget:self selector:@selector(handleRightSwipe:)]; 
rightSwipe.direction = UISwipeGestureRecognizerDirectionRight; 
rightSwipe.numberOfTouchesRequired = 1; 
[scrollView addGesture:rightSwipe]; 
[rightSwipe release]; 

y recuperar la imagen apropiada basada en el gesto y configurarlo usando imageView.image = yourImage;.

+0

Ok, eso funciona, pero quiero usar deslizar como toquesMovido, porque tengo que cambiar la imagen cuando estoy moviendo el dedo. Esto funciona con 1 movimiento, 1 cambio de imagen. –

+1

Hmm .. Puedo sugerirle que reemplace Swipe con reconocedores de gestos Pan.Configure el selector activado por el reconocedor de gestos pan para que se comporte como su método de toques movidos, ya que contiene los datos de traducción para que pueda trabajar. Pero esto requeriría que cada vista de imagen esté contenida dentro de un scrollView. –

+2

Alternativamente, puede ver la propiedad 'transform' en' UIImageView'. –

3

Finalmente, con la ayuda de Deepak, utilizo la propiedad de transformación de UIImageView para hacer el zoom.

Uso el CGFloat en la posición [0,0] en la matriz de CGAffineTransform para establecer los límites. Tengo que pasar el CGFloat a una cadena en el zoom porque cuando lo comparo con 0 esto siempre es cierto.

Por último, este es mi código en touchesMoved, si es útil para alguien:

// comparo para saber si el usuario esta haciendo zoom in o zoom out 
     if(initialDistance < finalDistance) { 
      NSLog(@"Zoom Out"); 

      CGAffineTransform transformer = CGAffineTransformScale(imagen.transform, 1.05, 1.05); 

      NSLog(@"transformer :: A: %.f, B: %.f, C: %.f, D: %.f", imagen.transform.a, imagen.transform.b, imagen.transform.c, imagen.transform.d); 

      if (transformer.a < 5) { 
       [UIView beginAnimations:nil context:NULL]; 
       [UIView setAnimationDuration: 0.2]; 
       imagen.transform = transformer; 
       [UIView setAnimationDelegate:self]; 
       [UIView commitAnimations]; 
      } 
     } 
     else { 
      NSLog(@"Zoom In"); 

      CGAffineTransform transformer = CGAffineTransformScale(imagen.transform, 0.95, 0.95); 

      NSLog(@"transformer :: A: %.f, B: %.f, C: %.f, D: %.f", transformer.a, transformer.b, transformer.c, transformer.d); 

      NSString *num = [NSString stringWithFormat:@"%.f", transformer.a]; 

      if (![num isEqualToString:@"0"]) { 
       [UIView beginAnimations:nil context:NULL]; 
       [UIView setAnimationDuration: 0.2]; 
       imagen.transform = transformer; 
       [UIView setAnimationDelegate:self]; 
       [UIView commitAnimations]; 
      } 
     } 

Y, por supuesto, un montón de gracias a Deepak.

Cuestiones relacionadas