Zoom in and zoom in, zoom in and out
Recently, I have been expanding, downgrading, and moving custom maps. Although the main functions are implemented, there are still many defects in details. Here I will share my code and ideas, hope you can get some advice.
To zoom in and out an image, my idea is to first determine whether to zoom in or out by changing the distance between two touch points, and then scale down the map image proportionally.
To move a map, first record the position at the beginning of the touch and the position at the touch movement, calculate the difference between the two, and then change the location of the map image accordingly. the two record points are constantly updated, so the image positions are constantly moving as the fingers change.
The following is the code.
1. Because the image is full screen and screens of different sizes need to be taken into account, the macro defines the imageView size (the screen size)
# Define SCREENHEIGHT [[UIScreen mainScreen] bounds]. size. height
# Define SCREENWIDTH [[UIScreen mainScreen] bounds]. size. width
2. Put an imageView in the xib file, the size is full screen, set constraints, and associate the. h file
When comparing touch points, at least two comparison objects are required. Therefore, you must declare
Double lastdistance; // used to record the distance between the last two points in the kneading gesture
@ Property (nonatomic, assign) CGPoint lastPoint; // record the previous position when moving
3. Allow the current view to execute a touch event
Self. view. multipleTouchEnabled = YES;
During the writing, I wrote the zoomed-in, zoomed-out, and moved the images together. However, for ease of understanding, I separated them by function here.
4. Zoom in and out the image
-(Void) touchesBegan :( NSSet *) touches withEvent :( UIEvent *) event {if (touches. count = 2) {NSArray * touchArray = [touches allObjects]; UITouch * firstTouch = [touchArray objectAtIndex: 0]; UITouch * secondTouch = [touchArray objectAtIndex: 1]; CGPoint point1 = [firstTouch locationInView: self. view]; CGPoint point2 = [secondTouch locationInView: self. view]; // calculate the distance between two points [(x1-x2) ^ 2 + (y1-y2) ^ 2] Open double distance = [self distance: point1 point: point2]; // assign a value to the last distance when the finger just touches the screen to prevent the first subtraction deviation from being too large because the last distance is empty when the finger is pressed. The image enlargement ratio is too high. lastdistance = distance ;}} -(void) touchesMoved :( NSSet *) touches withEvent :( UIEvent *) event {if (touches. count = 2) {NSArray * touchArray = [touches allObjects]; UITouch * firstTouch = [touchArray objectAtIndex: 0]; UITouch * secondTouch = [touchArray objectAtIndex: 1]; CGPoint point1 = [firstTouch locationInView: self. view]; CGPoint point2 = [secondTouch locationInView: self. view]; double distance = [self distance: point1 point: point2]; if (distance-lastdistance> 0) {int a = distance-lastdistance; // calculate the magnification float times = 1 + a * 0.005; CGSize bigSize = CGSizeMake (self. image. frame. size. width * times, self. image. frame. size. height * times); [self bigImageWithImage: self. image Size: bigSize] ;}else {int a = lastdistance-distance; float times = 1-a * 0.005; CGSize smallSize = CGSizeMake (self. image. frame. size. width * times, self. image. frame. size. height * times); [self smallImageWithImage: self. image Size: smallSize] ;}lastdistance = distance ;}- (double) distance :( CGPoint) p1 point :( CGPoint) p2 {double distance = sqrt (pow (p1.x-p2.x, 2) + pow (p1.y-p2.y, 2); return distance;} // enlarge the image-(void) bigImageWithImage :( UIImageView *) image Size :( CGSize) size {self. image. center = self. view. center; self. image. bounds = CGRectMake (0, 0, size. width, size. height);} // zoom out image-(void) smallImageWithImage :( UIImageView *) image Size :( CGSize) size {UIImageView * moveImage = image; if (size. height <= SCREENHEIGHT & size. width <= SCREENWIDTH) {moveImage. center = self. view. center; moveImage. bounds = CGRectMake (0, 0, SCREENWIDTH, SCREENHEIGHT);} else {self. image. center = self. view. center; self. image. bounds = CGRectMake (0, 0, size. width, size. height );}}
Image Movement
-(Void) touchesBegan :( NSSet *) touches withEvent :( UIEvent *) event {if (touches. count = 1) {UITouch * touch = [touches anyObject]; self. lastPoint = [touch locationInView: self. view] ;}}-(void) touchesMoved :( NSSet *) touches withEvent :( UIEvent *) event {if (touches. count = 1) {UITouch * touch = [touches anyObject]; CGPoint movePoint = [touch locationInView: self. view]; [self moveImage: movePoint] ;}// move an image-(void) moveImage :( CGPoint) movePoint {float x = movePoint. x-self. lastPoint. x; float y = movePoint. y-self. lastPoint. y; float newX = self. image. frame. origin. x + x; float newY = self. image. frame. origin. y + y; // determine to prevent image out of bounds if (newX> 0) {newX = 0;} if (newX <SCREENWIDTH-self.image.frame.size.width) {newX = SCREENWIDTH-self.image.frame.size.width ;} if (newY> 0) {newY = 0;} if (newY <SCREENHEIGHT-self.image.frame.size.height) {newY = SCREENHEIGHT-self.image.frame.size.height;} self. image. frame = CGRectMake (newX, newY, self. image. frame. size. width, self. image. frame. size. height); self. lastPoint = movePoint ;}
The biggest drawback of function implementation is that the center of the enlarged image is located in the center of the screen, where the image is enlarged by kneading. If you have a better method, please let me know.
The following is a demo of the effect:
Image enlargement and movement: