前沿 :
最近重新做了一個手勢的demo,其中有“點擊”,“長按”,“旋轉”,“拉升”等等在這里就不過多說明了,這些手勢都是我們手機上經常會用到的功能,所這部分內容還是比較重要的廢話也不多說了-上代碼。有些同樣的代碼小編只會寫一遍注釋。
等等---我忘記說了,在上代碼之前我們先看看小編的Assets.xcassets中的內容,這個里面放的都是圖片
現在如上面2張圖片可以看出在Assets.xcassets中 有23張圖片,有人會問要這么多圖片有什么用,其是也沒什么用處,小編在這里只是想實現一個動畫效果而已,那么在這里可以為大家普及一下知識。在我們所看到的動畫效果中,其實就是一張張圖片在不停切換,只不過速度太快了,我們的肉眼識別不出來而已,所以感覺就是在動。小編早這里就是想實現一個人在不停地奔跑的動畫效果,所以有23張圖片,當然你只要一張圖片也行。------咱們的標貼叫“手勢與動畫效果”,總得帶點動畫吧😁。
----感覺說的有點多了,下面正式上代碼。
在viewcontroller.m中
@interface ViewController ()<UIGestureRecognizerDelegate> @property (nonatomic,strong) UIImageView *imageview; @end
創建一個UIImageView對象,作用是放圖片。
首先我們要添加一個UIGestureRecognizerDelegate這個委托協議,我們要用到它的一個委托方法,
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
這個委托方法的作用就是檢測你的手勢,打個比方來說:有個拖動的手勢和一個滑動的手勢,那么怎么區分開來我是拖動還是滑動呢,這時就需要這個檢測方法來進行判斷了。
//遵守UIGestureRecognizerDelegate協議,作用是檢測手勢 -(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{ if ([gestureRecognizer isKindOfClass:[UIPinchGestureRecognizer class]] && [otherGestureRecognizer isKindOfClass:[UIRotationGestureRecognizer class]]) { return YES; } return NO; }
以上是這個檢測方法的實現代碼。
- (void)viewDidLoad { [super viewDidLoad]; //定義view的背景顏色 self.view.backgroundColor=[UIColor redColor]; //創建一個數組來放圖片 NSMutableArray *imageArray=[NSMutableArray arrayWithCapacity:0]; //把Assets.xcassets的圖片全部放入這個數字中 imageArray=[NSMutableArray arrayWithObjects: [UIImage imageNamed:@"timg-1"],[UIImage imageNamed:@"timg-2"], [UIImage imageNamed:@"timg-3"],[UIImage imageNamed:@"timg-4"], [UIImage imageNamed:@"timg-5"],[UIImage imageNamed:@"timg-6"], [UIImage imageNamed:@"timg-7"],[UIImage imageNamed:@"timg-8"], [UIImage imageNamed:@"timg-9"],[UIImage imageNamed:@"timg-10"], [UIImage imageNamed:@"timg-11"],[UIImage imageNamed:@"timg-12"], [UIImage imageNamed:@"timg-13"],[UIImage imageNamed:@"timg-14"], [UIImage imageNamed:@"timg-15"],[UIImage imageNamed:@"timg-16"], [UIImage imageNamed:@"timg-17"],[UIImage imageNamed:@"timg-18"], [UIImage imageNamed:@"timg-19"],[UIImage imageNamed:@"timg-20"], [UIImage imageNamed:@"timg-21"],[UIImage imageNamed:@"timg-22"], [UIImage imageNamed:@"timg-23"], nil ]; //設置UIimageView的坐標與大小(寬高) imageview=[[UIImageView alloc]initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)]; //設置在UIimageView中第一張圖片是數組的第一個對象 imageview.image=[imageArray firstObject]; //設置動畫效果 imageview.animationImages=imageArray; //設置播放速度0.0f-1.0f 1為正常速度,越小速度越快 imageview.animationDuration=0.2f; //設置圖片可以編輯(在下面的一些手勢需要) imageview.userInteractionEnabled=YES; //開始播放 [imageview startAnimating]; //在view中添加一個UIimageVIew [self.view addSubview:imageview]; //手勢 [self Gesture]; // Do any additional setup after loading the view, typically from a nib. }
在這小編先解釋一下,我們設置的view背景顏色為紅色,但是根本沒有紅色,那是因為view被UIImageView給擋了,
imageview=[[UIImageView alloc]initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
這里小編把 UIImageView的寬高設置為和view的寬高一樣大小。別急等下面我們講解手勢的時候,比如拖動,縮放等,就可以看到view了
這串代碼小編就不多說了,每一行都有注視說明,到了這一步小編的動畫效果就出來了:
怎么說呢,小編其實是想做一個GIF圖的,可是在其他電腦上加載不出來,不知道是不是太大的緣故,哎!!沒辦法小編就發3張圖片給大家湊合湊合吧。
手勢小知識:
UIGestureRecognizer將一些和手勢操作相關的方法抽象了出來,但它本身並不實現什么手勢我們也不會用到他,所以在開發中過程中,我們一般不會直接使用UIGestureRecognizer的對象,而是通過其子類進行實例化並實現手勢的功能。以下是幾種手勢
UITapGestureRecognizer 點擊手勢
UIPinchGestureRecognizer 縮放手勢
UIRotationGestureRecognizer 旋轉手勢
UISwipeGestureRecognizer 滑動手勢
UIPanGestureRecognizer 拖動手勢
UILongPressGestureRecognizer 長按手勢
一下是手勢的代碼:
1)點擊一下
UITapGestureRecognizer *TapGestureRecognizer=[[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(TapGesture:)]; //設置手指的個數為1個 TapGestureRecognizer.numberOfTouchesRequired=1; //遵守UIGestureRecognizerDelegate協議 TapGestureRecognizer.delegate=self; //添加這個手勢到UIimageView中 [imageview addGestureRecognizer:TapGestureRecognizer];
-(void)TapGesture:(UITapGestureRecognizer *)Tap{ NSLog(@"Tap------>%@",Tap); //判斷UIimageView是否在動畫中 if (imageview.isAnimating) { [imageview stopAnimating]; }else{ [imageview startAnimating]; } // if (Tap.state==UIGestureRecognizerStateEnded) { // [UIView animateWithDuration:1 delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{ // CGPoint point=self.view.center; // // Tap.view.center =CGPointMake(point.x, point.y-100) ; // // } completion:nil]; // // // [UIView animateWithDuration:1 delay:1 options:UIViewAnimationOptionCurveEaseOut animations:^{ // CGPoint point=self.view.center; // // Tap.view.center =CGPointMake(point.x, point.y+100); // CGPoint oo=CGPointMake(point.x, point.y+100); // } // // } completion:nil]; // } }
numberOfTouchesRequired // 手指數量個數;
numberOfTapsRequired // 連續輕拍次數;
-(void)TapGesture:(UITapGestureRecognizer *)Tap這個方法是自定義的,主要實現點擊后的效果,在這方中有一大串注釋過的代碼,其實就是實現一個動作效果而已,可以忽略,當然有興趣的可以去掉注釋,看看效果。這串代碼很少,其實就是一個判斷是否在動畫而已。
2)拖動效果
UIPanGestureRecognizer *PanGestureRecognizer=[[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(PanGesture:)]; PanGestureRecognizer.delegate=self; [imageview addGestureRecognizer:PanGestureRecognizer];
-(void)PanGesture:(UIPanGestureRecognizer *)Pan{ NSLog(@"Pan------>%@",Pan); //view上可以放控件,那么這個view就是這些控件的superView.而UIWindow上可以疊一層又一層的view,UIWindow就是這些view的superView.先放上去的index為0,然后依次累加 CGPoint point=[Pan translationInView:Pan.view.superview]; //中心點 CGPoint center=imageview.center; //設置中心坐標(x,y) center.x=center.x+point.x; center.y=center.y+point.y; imageview.center=center; [Pan setTranslation:CGPointZero inView:Pan.view]; //拖動結束后執行 if(Pan.state==UIGestureRecognizerStateEnded){ // imageview.center=self.view.center; // CGPoint velocity = [Pan velocityInView:self.view]; // CGFloat magnitude = sqrtf((velocity.x * velocity.x) + (velocity.y * velocity.y)); // CGFloat slideMult = magnitude / 200; // NSLog(@"magnitude: %f, slideMult: %f", magnitude, slideMult); // // float slideFactor = 0.1 * slideMult; // Increase for more of a slide // CGPoint finalPoint = CGPointMake(Pan.view.center.x + (velocity.x * slideFactor), // Pan.view.center.y + (velocity.y * slideFactor)); // finalPoint.x = MIN(MAX(finalPoint.x, 0), self.view.bounds.size.width); // finalPoint.y = MIN(MAX(finalPoint.y, 0), self.view.bounds.size.height); // [UIView animateWithDuration:1 delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{ Pan.view.center = self.view.center; } completion:nil]; } }
[Pan setTranslation:CGPointZero inView:Pan.view];這個方法網上介紹的很少,我總結了一下大概意思就是:清空(把Translation置零)移動的距離,有的解釋為“復位”,復位的意思就是歸零, 也可以叫初始化
UIGestureRecognizerStateEnded 拖動手勢結束后
[UIView animateWithDuration:1 delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{
Pan.view.center = self.view.center; } completion:nil];
以動畫的效果回到view 的終點。
3)上下滑效果
//向上滑動 UISwipeGestureRecognizer *SwipeGestureRecognizerUP=[[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(SwipeGestureUP:)]; SwipeGestureRecognizerUP.delegate=self; //上滑動 SwipeGestureRecognizerUP.direction=UISwipeGestureRecognizerDirectionUp; [imageview addGestureRecognizer:SwipeGestureRecognizerUP]; //向下滑動 UISwipeGestureRecognizer *SwipeGestureRecognizerDOWN=[[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(SwipeGestureDOWN:)]; SwipeGestureRecognizerDOWN.delegate=self; //下滑動 SwipeGestureRecognizerDOWN.direction=UISwipeGestureRecognizerDirectionDown; [imageview addGestureRecognizer:SwipeGestureRecognizerDOWN];
滑動分上滑動和下滑動,這里為了好看,我一起發了出來
typedef enum { UISwipeGestureRecognizerDirectionRight = 1 << 0, UISwipeGestureRecognizerDirectionLeft = 1 << 1, UISwipeGestureRecognizerDirectionUp = 1 << 2, } UISwipeGestureRecognizerDirection;
這是一個枚舉類型,滑動可以上下左右,這里我只區分了上下滑動
//向上滑動的效果 -(void)SwipeGestureUP:(UISwipeGestureRecognizer *)UP{ NSLog(@"UP------>%@",UP); //動畫的速度 float Duration=imageview.animationDuration; Duration=Duration-0.1; //判斷是否小於0 if (Duration<0) { Duration=0.1; } if (imageview.isAnimating) { //把新的動畫速度給UIimageView imageview.animationDuration=Duration; [imageview startAnimating]; }else{ imageview.animationDuration=Duration; } } //向下滑動的效果 -(void)SwipeGestureDOWN:(UISwipeGestureRecognizer *)DOWN{ NSLog(@"DOWN------>%@",DOWN); float Duration=imageview.animationDuration; Duration=Duration+0.1; if (Duration>1.0) { Duration=1.0; } if (imageview.isAnimating) { imageview.animationDuration=Duration; [imageview startAnimating]; }else{ imageview.animationDuration=Duration; } }
imageview.animationDuration設置動畫速度,上滑動就是加速度,下滑動就是減速度。然后重新復制給imageview.animationDuration來改變動畫的速度。
4)長按效果
UILongPressGestureRecognizer *LongPressGestureRecognizer=[[UILongPressGestureRecognizer alloc]initWithTarget:self action:@selector(LongPressGesture:)]; //長安時間為0.5秒 LongPressGestureRecognizer.minimumPressDuration=0.5f; LongPressGestureRecognizer.delegate=self; [imageview addGestureRecognizer:LongPressGestureRecognizer];
//長按的效果 -(void)LongPressGesture:(UILongPressGestureRecognizer *)LongPress{ NSLog(@"LongPress------>%@",LongPress); //LongPress.allowableMovement = 10; }
minimumPressDuration: 長按生效時間
allowableMovement: 長按有效移動范圍(從點擊開始,長按移動的允許范圍)
5)放大縮小效果
UIPinchGestureRecognizer *PinchGestureRecognizer=[[UIPinchGestureRecognizer alloc]initWithTarget:self action:@selector(PinchGesture:)]; PinchGestureRecognizer.delegate=self; [imageview addGestureRecognizer:PinchGestureRecognizer];
//放大縮小的效果 -(void)PinchGesture:(UIPinchGestureRecognizer *)Pinch{ NSLog(@"Pinch------>%@",Pinch); imageview.transform=CGAffineTransformScale(imageview.transform, Pinch.scale, Pinch.scale); Pinch.scale=1; }
CGAffineTransformScale縮放:設置縮放比例
scale縮放比例(手指距離增大,scale增大) // scale = 1.0
以下是效果圖
6)旋轉效果
UIRotationGestureRecognizer *RotationGestureRecognizer=[[UIRotationGestureRecognizer alloc]initWithTarget:self action:@selector(RotationGesture:)]; RotationGestureRecognizer.delegate=self; [imageview addGestureRecognizer:RotationGestureRecognizer];
-(void)RotationGesture:(UIRotationGestureRecognizer *)Rotation{ NSLog(@"Rotation------>%@",Rotation); imageview.transform=CGAffineTransformRotate(imageview.transform, Rotation.rotation); Rotation.rotation=0; }
CGAffineTransformMakeRotation 旋轉:設置旋轉角度
velocity :速度
rotation 旋轉的弧度
Rotation.rotation = 0;
將旋轉的弧度清0(將當前手勢旋轉的弧度清0);
-----------------------------------------------------目前幾個手勢的功能就基本實現了,希望我的筆記可以幫打你們
一下是效果圖