objective c - how - ¿Cómo puedo acercar y alejar un UIImageView sin UIScrollView?
uiimageview swift 4 (2)
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).
Bueno, entonces muestro la primera imagen en 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 hacia arriba, la descargo, y también con la derecha y la izquierda.
Todo esto está hecho. 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 -> es 0
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.
De acuerdo. Puede considerar usar UIScrollView solo para usarlo para su funcionalidad de zoom.
Supongamos que tenemos un scrollView
y un imageView
con ambos límites. Agregue imageView
como subvista de scrollView
.
[scrollView addSubview:imageView];
scrollView.contentSize = imageView.frame.size;
Para admitir solo el zoom y no la panorámica en el scrollView
su viewController
deberá 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 UISwipeGestureRecognizers configurados apropiadamente . 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 recupera la imagen apropiada basada en el gesto y imageView.image = yourImage;
usando imageView.image = yourImage;
.
Finalmente, con la ayuda de Deepak, utilizo la propiedad de transformación de UIImageView para hacer el zoom.
Utilizo 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.
Finalmente 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, muchas gracias a Deepak.