各種觸摸手勢


輕按(UITapGestureRecognizer) -- 用一個或多個手指在屏幕上輕按。

按住(UILongPressGestureRecognizer) -- 用一個或多個手指在屏幕上按住。

輕掃(UISwipeGestureRecognizer) -- 用一個或多個手指沿特定方向輕掃。

張合(UIPinchGestureRecognizer) -- 張合手指以縮放對象。

旋轉(UIRotationGestureRecognizer) -- 沿圓形滑動兩個手指。

平移(UIPanGestureRecognizer) -- 觸摸並拖曳。

通過指定要使用的識別器(Recognizer)類型,並將其加入到視圖(UIView)中,就能自動收到觸發的多點觸摸事件。有兩種方式添加手勢識別器:使用代碼或使用Interface Builder編輯器以可視化方式添加。

可視化方式添加手勢識別器:

1. 先找到手勢控件組

2. 選中某一識別器,直接拖拽到控件上

識別器將作用於該控件,實際是增加了一個屬性名為"gestureRecognizers"與該控件的連接。一個識別器可以連接多個控件:

需要注意的是,有一些控件(例如Label)默認沒有允許"User Interaction Enabled"。這樣手勢將不生效,需要勾選后手勢才能生效,對應的方法是setUserInteractionEnabled。

3. 定義操作

代碼添加手勢識別器:

- (IBAction)testTap:(id)sender 
{
    NSLog(@"Tap");
    
    //得到觸點在視圖中的坐標
    CGPoint point = [(UITapGestureRecognizer*)sender locationInView:self.btnTest];
    NSLog(@"x:%.2f,y:%.1f",point.x,point.y);
}

- (void)viewDidLoad
{
    UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(testTap:)];
    tapRecognizer.numberOfTapsRequired = 1;
    tapRecognizer.numberOfTouchesRequired = 1;
    [self.btnTest addGestureRecognizer:tapRecognizer];
    
    [super viewDidLoad];
}

代碼里的initWithTarget:self,是指明方法testTap所屬的對象。大多數情況下簡單指定為當前類就夠了,但有時候也會寫在外部類:

#import <Foundation/Foundation.h>

@interface MyClass : NSObject

- (void)testTap;

@end
MyClass.h
#import "MyClass.h"

@implementation MyClass

- (void)testTap
{
    NSLog(@"a tap!");
}
MyClass.m
#import <UIKit/UIKit.h>
#import "MyClass.h"

@interface ViewController : UIViewController
{
    MyClass *myClass;
}

@property (strong, nonatomic) IBOutlet UIButton *btnTest;

@end
ViewController.h
#import "ViewController.h"
#import "MyClass.h"

@implementation ViewController
@synthesize btnTest;

- (void)viewDidLoad
{
    myClass = [[MyClass alloc] init];
    
    UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:myClass action:@selector(testTap)];
    [self.btnTest addGestureRecognizer:tapRecognizer];
    
    [super viewDidLoad];
}
ViewController.m

注意:MyClass *myClass一定要聲明在頭文件ViewController.h,如果聲明在ViewController.m會找不到testTap方法。這是因為在ViewController.m里會把MyClass聲明成立局部變量,導致MyClass中的action不能正確識別自身所屬的類。

輕按(UITapGestureRecognizer) 

輕按手勢可以設定按下次數和觸點數:

numberOfTapsRequired -- 需要輕按對象多少次才能識別出輕按手勢,默認為1。

numberOfTouchesRequired -- 需要有多少個手指在對象上才能識別出輕按手勢,默認為1。

輕掃(UISwipeGestureRecognizer) 

輕掃手勢可以設定方向和觸點數:

direction -- 輕掃方向,值是枚舉UISwipeGestureRecognizerDirection中的一個,分別為:

UISwipeGestureRecognizerDirectionRight(向右,默認值)
UISwipeGestureRecognizerDirectionLeft(向左)
UISwipeGestureRecognizerDirectionUp(向上)
UISwipeGestureRecognizerDirectionDown(向下)

numberOfTouchesRequired -- 需要有多少個手指在對象上才能識別出輕按手勢,默認為1。

P.s 如果要識別並相應不同的輕掃方向,必須實現多個輕掃手勢識別器。通過編寫代碼,可讓一個輕掃手勢識別器響應多個輕掃方向,但無法區分不同的輕掃方向。例如:

- (void)viewDidLoad
{    
    UISwipeGestureRecognizer *leftSwipeGesture = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(testSwipe:)];
    leftSwipeGesture.direction = UISwipeGestureRecognizerDirectionLeft;
    [self.btnTest addGestureRecognizer:leftSwipeGesture];
    
    UISwipeGestureRecognizer *upSwipeGesture = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(testSwipe:)];
    upSwipeGesture.direction = UISwipeGestureRecognizerDirectionUp;
    [self.btnTest addGestureRecognizer:upSwipeGesture];
    
    [super viewDidLoad];
}

- (IBAction)testSwipe:(id)sender 
{
    UISwipeGestureRecognizer *swipeGesture = (UISwipeGestureRecognizer *)sender;
    if(swipeGesture.direction==UISwipeGestureRecognizerDirectionLeft)
    {
        NSLog(@"left swipe!");
    }
    else if(swipeGesture.direction==UISwipeGestureRecognizerDirectionUp)
    {
        NSLog(@"up swipe!");
    }
}

張合(UIPinchGestureRecognizer) 

輕掃手勢可以設定縮放值和速度:

scale -- 默認為1。在必要的情況下可以通過改變這個值來調整放大縮小因子

velocity -- (張合手勢發生的)速度,初始值為0。

- (void)viewDidLoad
{    
    UIPinchGestureRecognizer *pinchGesture = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(testPinch:)];
    [self.imgView1 addGestureRecognizer:pinchGesture];
    [self.imgView1 setUserInteractionEnabled:YES];
    [super viewDidLoad];
}

- (IBAction)testPinch:(id)sender 
{
    CGFloat scale = ((UIPinchGestureRecognizer *)sender).scale;
    
    self.imgView1.frame = CGRectMake(self.imgView1.frame.origin.x, 
                                     self.imgView1.frame.origin.y, 
                                     self.imgView1.frame.size.width*scale, 
                                     self.imgView1.frame.size.height*scale);
}

旋轉(UIRotationGestureRecognizer) 

旋轉手勢可以設定旋轉角度和速度:

rotation -- 旋轉角度(弧度值,可通過公式轉換:度數=弧度數*180/Pi,弧度數=度數*Pi/180),初始值為0,隨着每個旋轉手勢逐漸累積。可以將默認的初始旋轉角度0修改為任何值,這樣后續的旋轉手勢將以指定的值為起點。

velocity -- 速度,初始值為0。

- (void)viewDidLoad
{
    UIRotationGestureRecognizer *rotationGesture = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:@selector(testRotation:)];
    
    [self.imgView1 addGestureRecognizer:rotationGesture];
    [self.imgView1 setUserInteractionEnabled:YES];
    [super viewDidLoad];
}

- (IBAction)testRotation:(id)sender 
{
    CGFloat rotation = ((UIRotationGestureRecognizer *)sender).rotation;
    
    self.imgView1.transform = CGAffineTransformMakeRotation(rotation);
}

搖動識別器

搖動的處理方式與其它手勢不同,必須攔截一個類型為UIEventTypeMotion的UIEvent。為此,視圖或視圖控制器必須是響應者鏈中的第一響應者(FirstResponder),還必須實現方法motionEnded:withEvent。

step 1. 成為第一響應者(FirstResponder)

通過方法canBecomeFirstResponder允許視圖控制器成為第一響應者,這個方法除了返回YES外什么都不做:

- (BOOL)canBecomeFirstResponder
{
    return YES;
}

在視圖控制器加載視圖后立即發送消息becomeFirstResponder,讓視圖成為第一響應者:

- (void)viewDidAppear:(BOOL)animated
{
    [self becomeFirstResponder];
    [super viewDidAppear:animated];
}

step 2. 響應搖動手勢

實現方法motionEnded:withEvent:

- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event
{
    if(motion == UIEventSubtypeMotionShake)
    {
        NSLog(@"Shaking things up!");
    }
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM