捏合圖片放大縮小與移動,捏合圖片放大縮小
最近在做自訂地圖的放大縮小與移動,雖然實現了主要功能,但是在細節上還是有很多缺陷瑕疵,在這裡將代碼和思路分享一下,希望能夠拋磚引玉,得到高人指點.
實現圖片的放大與縮小,我的思路是先通過兩個觸摸點距離的變化,判斷是放大還是縮小,然後再把地圖圖片按比例放大縮小.
地圖的移動,先記錄觸摸開始時的位置和觸摸移動的位置,計算兩者之間的差,再相應更改地圖圖片的位置.兩個記錄點不斷更新,所以圖片位置也隨著手指的變動不斷移動.
基本思路介紹完了,以下是代碼.
1.因為圖片是全屏的,同時還要考慮不同尺寸的螢幕,所以宏定義imageView的大小(螢幕的大小)
#define SCREENHEIGHT [[UIScreen mainScreen] bounds].size.height
#define SCREENWIDTH [[UIScreen mainScreen] bounds].size.width
2.在xib檔案中放入一個imageView,大小為全屏,設定約束,並關聯.h檔案
觸摸點進行比較時需要至少兩個比較對象,所以在.h中需要聲明
double lastdistance;//在捏合手勢中用來記錄上一次兩點之間距離
@property(nonatomic,assign)CGPoint lastPoint;//移動時記錄上一次位置
3.允許當前view執行觸摸事件
self.view.multipleTouchEnabled=YES;
在寫的時候我將圖片的放大縮小移動寫在了一起,但是為了方便理解,在這裡我將他們按功能分開
4.圖片放大縮小
-(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]; //計算兩點距離[(x1-x2)^2+(y1-y2)^2]開方 double distance=[self distance:point1 point:point2]; //在手指剛觸控螢幕幕時給last distance賦值,防止在手指捏合時因為last distance為空白,造成第一次相減差太大,圖片放大比例太高 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;//計算放大倍數 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; }//放大圖片-(void)bigImageWithImage:(UIImageView *)image Size:(CGSize)size{ self.image.center=self.view.center; self.image.bounds=CGRectMake(0, 0, size.width, size.height);}//縮小圖片-(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); }}
圖片移動
-(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]; } }//移動圖片-(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; //判斷,防止圖片越界 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;}
功能實現最大的缺陷是每次放大圖片的中心會重新置放到螢幕中心,在那裡捏合就在那裡放大.如果有更好地方法請告訴我.
下面是效果示範:
圖片放大與移動: