三、用手势识别响应事件
There are three things you do to add a built-in gesture recognizer to your app:
你需要做三件事来添加一个内建手势识别到应用程序:
Create and configure a gesture recognizer instance.
创建并配置一个手势识别实例。
This step includes assigning a target, action, and sometimes assigning gesture-specific attributes (such as the numberOfTapsRequired
).
该步骤包括分配一个目标,操作,以及有时候分配手势指定的各种属性(比如 numberOfTapsRequired).
Attach the gesture recognizer to a view.
把手势识别连接到一个视图。
Implement the action method that handles the gesture.
实现处理手势的操作方法。
1、使用界面生成器(Interface Builder)来添加一个手势识别到应用程序
Within Interface Builder in Xcode, add a gesture recognizer to your app the same way you add any object to your user interface—drag the gesture recognizer from the object library to a view. When you do this, the gesture recognizer automatically becomes attached to that view. You can check which view your gesture recognizer is attached to, and if necessary, change the connection in the nib file.
在Xcode里的界面生成器中,添加手势识别到应用程序跟你添加任何对象到用户界面(add any object to your user interface)是一样的---就是从对象库中拖拉手势识别到一个视图。完成该操作后,手势识别自动连接到那个视图。 你可以检查手势识别被连接到了哪个视图,并且如果必要,在nib 文件中更改该连接(change the connection in the nib file)。
After you create the gesture recognizer object, you need to create and connect an action method. This method is called whenever the connected gesture recognizer recognizes its gesture. If you need to reference the gesture recognizer outside of this action method, you should also create and connect an outlet for the gesture recognizer. Your code should look similar to Listing 1-1.
当你创建完手势识别对象后,你需要创建并连接一个操作方法(create and connect an action)。任何时候手势识别(gesture recognizer)识别手势时都将调用该方法。如果你需要在该操作方法外面引用手势识别,你还应该为手势识别创建并连接一个输出口 (create and connect an outlet)。你的代码应该跟列表1-1相似.
Adding a gesture recognizer to your app with Interface Builder
列表1-1 用界面生成器添加一个手势识别到应用程序
@interface APLGestureRecognizerViewController () |
@property (nonatomic, strong) IBOutlet UITapGestureRecognizer *tapRecognizer; |
@end |
@implementation |
- (IBAction)displayGestureForTapRecognizer:(UITapGestureRecognizer *)recognizer |
// Will implement method later... |
} |
@end |
2、通过程序添加一个手势识别
You can create a gesture recognizer programmatically by allocating and initializing an instance of a concrete UIGestureRecognizer
subclass, such asUIPinchGestureRecognizer
. When you initialize the gesture recognizer, specify a target object and an action selector, as in Listing 1-2. Often, the target object is the view’s view controller.
你可以通过分配和初始化一个具体(concrete)的UIGestureRecognizer 子类的实例来创建一个手势识别,比如 UIPinchGestureRecognizer 。 当你初始化手势识别时,指定一个目标对象和一个操作选择器(selector),正如列表1-2中所示,通常目标对象就是视图的视图控制器。
If you create a gesture recognizer programmatically, you need to attach it to a view using the addGestureRecognizer:
method. Listing 1-2 creates a single tap gesture recognizer, specifies that one tap is required for the gesture to be recognized, and then attaches the gesture recognizer object to a view. Typically, you create a gesture recognizer in your view controller’s viewDidLoad
method, as shown in Listing 1-2.
如果你通过程序创建一个手势识别,你需要调用addGestureRecognizer: 方法来把它连接到视图。 列表1-2 创建了一个单个轻击手势识别,指定识别该手势需要一次轻击(tap),然后把手势识别对象连接到一个视图。 通常,你在视图控制器的
viewDidLoad 方法里创建手势识别,如列表1-2所示。
Creating a single tap gesture recognizer programmatically
列表1-2 通过程序创建一个单一的轻击手势识别
- (void)viewDidLoad { |
[super viewDidLoad]; |
// Create and initialize a tap gesture |
UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] |
initWithTarget:self action:@selector(respondToTapGesture:)]; |
// Specify that the gesture must be a single tap |
tapRecognizer.numberOfTapsRequired = 1; |
// Add the tap gesture recognizer to the view |
[self.view addGestureRecognizer:tapRecognizer]; |
// Do any additional setup after loading the view, typically from a nib |
} |
3、响应离散手势
When you create a gesture recognizer, you connect the recognizer to an action method. Use this action method to respond to your gesture recognizer’s gesture.Listing 1-3 provides an example of responding to a discrete gesture. When the user taps the view that the gesture recognizer is attached to, the view controller displays an image view that says “Tap.” The showGestureForTapRecognizer:
method determines the location of the gesture in the view from the recognizer’slocationInView:
property and then displays the image at that location.
当你创建一个手势识别时,你把该识别(recognizer)连接到一个操作方法。使用该操作方法来响应手势识别的手势。列表1-3 提供了一个响应一个离散手势的例子。 当用户轻击了带有手势识别的视图时,视图控制器显示一个图像视图(image view)表示"Tap"发生。 showGestureForTapRecognizer: 方法决定了视图中手势的位置,该位置从recognizer的locationInView: 特性中获取,然后把图片显示到该位置。
Note: The next three code examples are from the Simple Gesture Recognizers sample code project, which you can examine for more context.
注意: 接下来的3段代码例子取自 Simple Gesture Recognizers 样本代码工程,你可以查看它以获得更多上下文。
Handling a double tap gesture
列表1-3 处理一个双击手势
- (IBAction)showGestureForTapRecognizer:(UITapGestureRecognizer *)recognizer { |
// Get the location of the gesture |
CGPoint location = [recognizer locationInView:self.view]; |
// Display an image view at that location |
[self drawImageForGestureRecognizer:recognizer atPoint:location]; |
// Animate the image view so that it fades out |
[UIView animateWithDuration:0.5 animations:^{ |
self.imageView.alpha = 0.0; |
}]; |
} |
Each gesture recognizer has its own set of properties. For example, in Listing 1-4, the showGestureForSwipeRecognizer:
method uses the swipe gesture recognizer’s direction
property to determine if the user swiped to the left or to the right. Then, it uses that value to make an image fade out in the same direction as the swipe.
每个手势识别都有它自己的特性集。比如,如列表1-4中,showGestureForSwipeRecognizer: 方法使用点击(swipe)手势识别的direction 特性来决定用户是向左清扫还是向右。 然后,它使用该值来让图像从点击方向消失。
Responding to a left or right swipe gesture
列表1-4 响应一个向左或向右清扫手势
// Respond to a swipe gesture |
- (IBAction)showGestureForSwipeRecognizer:(UISwipeGestureRecognizer *)recognizer { |
// Get the location of the gesture |
CGPoint location = [recognizer locationInView:self.view]; |
// Display an image view at that location |
[self drawImageForGestureRecognizer:recognizer atPoint:location]; |
// If gesture is a left swipe, specify an end location |
// to the left of the current location |
if (recognizer.direction == UISwipeGestureRecognizerDirectionLeft) { |
location.x -= 220.0; |
} else { |
location.x += 220.0; |
} |
// Animate the image view in the direction of the swipe as it fades out |
[UIView animateWithDuration:0.5 animations:^{ |
self.imageView.alpha = 0.0; |
self.imageView.center = location; |
}]; |
} |
4、响应连续手势
Continuous gestures allow your app to respond to a gesture as it is happening. For example, your app can zoom while a user is pinching or allow a user to drag an object around the screen.
连续手势允许应用程序在手势发生时响应。 比如,用户可以一边做捏合手势,一边就可以看见缩放,或者允许用户沿着屏幕拖拉一个对象。
Listing 1-5 displays a “Rotate” image at the same rotation angle as the gesture, and when the user stops rotating, animates the image so it fades out in place while rotating back to horizontal. As the user rotates his fingers, the showGestureForRotationRecognizer:
method is called continually until both fingers are lifted.
列表1-5 以跟手势同样的角度显示一个"Rotate"图片,并且当用户停止旋转时,动画该图片让其在旋转回水平方向的同时消失。 当用户旋转他的手指时,持续调用 showGestureForRotationRecognizer: 方法直到两个手指都拿起。
Responding to a rotation gesture
列表1-5 响应一个旋转手势
// Respond to a rotation gesture |
- (IBAction)showGestureForRotationRecognizer:(UIRotationGestureRecognizer *)recognizer { |
// Get the location of the gesture |
CGPoint location = [recognizer locationInView:self.view]; |
// Set the rotation angle of the image view to |
// match the rotation of the gesture |
CGAffineTransform transform = CGAffineTransformMakeRotation([recognizer rotation]); |
self.imageView.transform = transform; |
// Display an image view at that location |
[self drawImageForGestureRecognizer:recognizer atPoint:location]; |
// If the gesture has ended or is canceled, begin the animation |
// back to horizontal and fade out |
if (([recognizer state] == UIGestureRecognizerStateEnded) || ([recognizer state] == UIGestureRecognizerStateCancelled)) { |
[UIView animateWithDuration:0.5 animations:^{ |
self.imageView.alpha = 0.0; |
self.imageView.transform = CGAffineTransformIdentity; |
}]; |
} |
} |
Each time the method is called, the image is set to be opaque in the drawImageForGestureRecognizer:
method. When the gesture is complete, the image is set to be transparent in the animateWithDuration:
method. The showGestureForRotationRecognizer:
method determines whether a gesture is complete by checking the gesture recognizer’s state. These states are explained in more detail in “Gesture Recognizers Operate in a Finite State Machine.”
每次调用该方法时,图片都在drawImageForGestureRecognizer: 方法中被设置为不透明。 当手势完成时,图片在animateWithDuration: 方法中被设置为透明。showGestureForRotationRecognizer:方法通过检查手势识别的状态来判断手势是否完成。 关于这些状态的更多信息,请看“Gesture Recognizers Operate in a Finite State Machine.”