Detailed use of IOS gesture recognition (drag, zoom, rotate, click, gesture dependent, custom gesture) _ios

Source: Internet
Author: User
Tags inheritance touch uikit

Gesture recognition is important in iOS, and gesture manipulation is an important feature of mobile devices, greatly increasing the ease of use of mobile devices.

1, Uigesturerecognizer Introduction

Gesture recognition is important in iOS, and gesture manipulation is an important feature of mobile devices, greatly increasing the ease of use of mobile devices.

iOS system after 3.2, to facilitate the development of this use of some commonly used gestures, provides the Uigesturerecognizer class. The gesture recognition Uigesturerecognizer class is an abstract class, and the following subclasses are specific gestures that can be identified directly using these gestures.

    • UITapGestureRecognizer
    • Uipinchgesturerecognizer
    • Uirotationgesturerecognizer
    • Uiswipegesturerecognizer
    • Uipangesturerecognizer
    • Uilongpressgesturerecognizer

The above gestures correspond to the following actions:

    • Tap (click)
    • Pinch (two fingers inward or outward, usually used to zoom)
    • Rotation (rotation)
    • Swipe (sliding, fast moving)
    • Pan (drag, slow move)
    • Longpress (Long Press)

The inheritance relationship of the Uigesturerecognizer is as follows:

2. Steps to use gestures

Using gestures is simple and is divided into two steps:

Creates a gesture instance. When a gesture is created, a callback method is specified, and the callback method is invoked when the gesture begins, changes, or ends.

Add to the view you want to identify. Each gesture corresponds to only one view, and when the screen touches within the bounds of the view, if the gesture is the same as the reservation, then the method is recalled.

PS: A gesture can only correspond to one view, but a view can have multiple gestures.

It is recommended that you run these gestures on the real machine and that the simulator is not easy to operate and may cause you to think that the gesture is ineffective.

3. Pan Drag gesture:

Uiimageview *snakeimageview = [[Uiimageview alloc] initwithimage:[uiimage imagenamed:@ "Snake.png"]]; 
Snakeimageview.frame = CGRectMake (M, M, 160); 
Uipangesturerecognizer *pangesturerecognizer = [[Uipangesturerecognizer alloc] 
                        initwithtarget:self 
                        Action: @selector (Handlepan:)];   
[Snakeimageview Addgesturerecognizer:pangesturerecognizer]; 
[Self.view Setbackgroundcolor:[uicolor Whitecolor]]; 

Create a new ImageView, and then add gestures

Callback method:

-(void) Handlepan: (uipangesturerecognizer*) recognizer 
{ 
  cgpoint translation = [Recognizer Translationinview : Self.view]; 
  Recognizer.view.center = Cgpointmake (recognizer.view.center.x + translation.x, 
                  recognizer.view.center.y + TRANSLATION.Y); 
  [Recognizer Settranslation:cgpointzero InView:self.view]; 
   
} 

4. Pinch zoom gesture

Uipinchgesturerecognizer *pinchgesturerecognizer = [[Uipinchgesturerecognizer alloc] 
                            initwithtarget:self 
                            
-(void) Handlepinch: (uipinchgesturerecognizer*) recognizer 
{ 
  Recognizer.view.transform = Cgaffinetransformscale (Recognizer.view.transform, Recognizer.scale, Recognizer.scale); 
  Recognizer.scale = 1; 

5. Rotation rotation gesture

Uirotationgesturerecognizer *rotaterecognizer = [[Uirotationgesturerecognizer alloc] 
                         initwithtarget:self 
                         Action: @selector (handlerotate:)]; 
-(void) Handlerotate: (uirotationgesturerecognizer*) recognizer 
{ 
  Recognizer.view.transform = Cgaffinetransformrotate (Recognizer.view.transform, recognizer.rotation); 
  recognizer.rotation = 0; 

After adding these gestures, run to see the effect, the program in the ImageView put a

/^\/^\
_|__| o|
\/     /~     \_/ \
\____|__________/  \
\_______      \
`\     \                 \
|                  | \
/      /                    \
/     /                       \\
/      /                         \ \
/     /                            \  \
/     /             _----_            \   \
/     /           _-~      ~-_         | |
(      (        _-~    _--_    ~-_     _/   |
\      ~-____-~    _-~    ~-_    ~-_-~    /
~-_           _-~          ~-_       _-~
~--______-~                ~-___-~

Picture, drag on the emulator is no problem. There is a problem with scaling and rotation, which is estimated because the two contact points on the simulator are away from the ImageView boundary, so the operation is ineffective.

It is recommended that you run this gesture on the real machine.

Zoom and select the operating tips on the simulator:

You can set the frame value of the ImageView a bit larger, hold down the ALT key, press the Touchpad (not press the No), so you can rotate and zoom.

6, add a second imagview and add gestures

Remember: A gesture can only be added to one view, two view of course there are two examples of gestures

-(void) viewdidload {[Super viewdidload]; 
  Uiimageview *snakeimageview = [[Uiimageview alloc] initwithimage:[uiimage imagenamed:@ "Snake.png"]]; 
  Uiimageview *dragonimageview = [[Uiimageview alloc] initwithimage:[uiimage imagenamed:@ "Dragon.png"]]; 
  Snakeimageview.frame = CGRectMake (120, 120, 100, 160); 
  Dragonimageview.frame = CGRectMake (50, 50, 100, 160); 
  [Self.view Addsubview:snakeimageview]; 
   
  [Self.view Addsubview:dragonimageview]; For (UIView *view in self.view.subviews) {Uipangesturerecognizer *pangesturerecognizer = [[Uipangesturerecognizer al 
     
    LOC] Initwithtarget:self action: @selector (Handlepan:)]; Uipinchgesturerecognizer *pinchgesturerecognizer = [[Uipinchgesturerecognizer alloc] In 
     
    Itwithtarget:self Action: @selector (handlepinch:)]; Uirotationgesturerecognizer *rotaterecognizer = [[UirotationgesturerecognizEr alloc] initwithtarget:self action: @selector (handlerotate:)] 
     
    ; 
    [View Addgesturerecognizer:pangesturerecognizer]; 
    [View Addgesturerecognizer:pinchgesturerecognizer]; 
    [View Addgesturerecognizer:rotaterecognizer]; 
  [View Setuserinteractionenabled:yes];    
} [Self.view Setbackgroundcolor:[uicolor Whitecolor]]; 
 }

Add more than one-stop view, two view can receive the above three kinds of gestures. The operation effect is as follows:

7, drag (pan gesture) speed (drag and drop at a faster speed view has the effect of sliding)
How to achieve it?

    • Monitoring whether gestures are over
    • Monitor the speed of the touch
-(void) Handlepan: (uipangesturerecognizer*) recognizer {cgpoint translation = [Recognizer TranslationInView:self.vi 
  EW]; Recognizer.view.center = Cgpointmake (recognizer.view.center.x + translation.x, Recognizer.view.center 
  . Y + translation.y); 
   
  [Recognizer Settranslation:cgpointzero InView:self.view]; if (recognizer.state = = uigesturerecognizerstateended) {Cgpoint velocity = [Recognizer VelocityInView:self.vie 
    W]; 
    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 (recognizer.view.center.x + (velocity.x * slidefactor 
    ), Recognizer.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:slidefactor*2 delay:0 options:uiviewanimationoptioncurveeaseout animations:^{recognize 
    R.view.center = Finalpoint; 
     
  } Completion:nil];  }

Code implementation Resolution:

    • Compute the length of the speed vector (most of which is forgotten).
    • If the speed vector is less than 200, you get a decimal number that is less than the number, then the slide will be very short
    • Calculate an endpoint based on speed and velocity factors
    • Make sure the endpoint doesn't run out of the parent view's bounds
    • Use the UIView animation to slide the view to the end

After running, quickly drag the image view to let go and see that the view will also glide a little way in the same direction.

8. Simultaneous gestures that trigger two view

Gestures are mutually exclusive, and if you want to trigger the view of snakes and dragons at the same time, you need to implement the Protocol

Uigesturerecognizerdelegate,

@interface viewcontroller:uiviewcontroller<uigesturerecognizerdelegate> 

And return Yes in this method of protocol.

-(BOOL) Gesturerecognizer: (Uigesturerecognizer *) Gesturerecognizer Shouldrecognizesimultaneouslywithgesturerecognizer: (Uigesturerecognizer *) Othergesturerecognizer 
{ 
  return YES; 

Set the self as a proxy to the gesture:

Pangesturerecognizer.delegate = self; 
Pinchgesturerecognizer.delegate = self; 

This allows you to drag or rotate the zoom two view at the same time.

9, tap tap gesture

Here to see the effect of tap, play a sound when you click on the screen.

To play the sound, we joined the Avfoundation.framework this frame.

-(Avaudioplayer *) Loadwav: (NSString *) filename { 
  nsurl * url = [[NSBundle mainbundle] Urlforresource:filename Withex tension:@ "wav"]; 
  Nserror * ERROR; 
  Avaudioplayer * player = [[Avaudioplayer alloc] Initwithcontentsofurl:url error:&error]; 
  if (!player) { 
    NSLog (@ "Error loading%@:%@", url, error.localizeddescription); 
  } else { 
    [player Preparetoplay]; 
  } 
  return player; 
} 

I'll give the complete code in the final example code, and the steps to add the gesture are the same as before.

#import <UIKit/UIKit.h> 
#import <AVFoundation/AVFoundation.h> 
 
@interface Viewcontroller: Uiviewcontroller<uigesturerecognizerdelegate> 
@property (Strong) Avaudioplayer * Chompplayer; 
@property (Strong) Avaudioplayer * Heheplayer; 
 
@end 
-(void) Handletap: (UITapGestureRecognizer *) recognizer { 
  [self.chompplayer play]; 
} 

Run, click on a picture, will play a bite of the sound.

However, this click to play a little bit of a flaw in the sound, is slowly dragging the time will also play. This makes two gestures coincide. How to solve it? Used for gestures:

Requiregesturerecognizertofail method.

10. The dependence of gesture

Add this code in the Viewdidload loop:

 
 

This means that when the pan gesture fails, it does not drag, and the tap gesture is started. So if you have a slight drag, the pan gesture happens. The TAP's voice won't come out.

11. Custom gestures

Custom gesture Inheritance: Uigesturerecognizer, implement the following methods:

–touchesbegan:withevent: 
–touchesmoved:withevent: 
–touchesended:withevent: 

Create a new class, Inherit Uigesturerecognizer, code as follows:
. h Files

#import <UIKit/UIKit.h> 
typedef enum { 
  Directionunknown = 0, 
  directionleft, 
  directionright 
} Direction; 
 
@interface Happygesturerecognizer:uigesturerecognizer 
@property (assign) int ticklecount; 
@property (assign) Cgpoint Curticklestart; 
@property (assign) Direction lastdirection; 
 
@end 

. m file

#import "HappyGestureRecognizer.h" #import <UIKit/UIGestureRecognizerSubclass.h> #define Required_tickles 2 # Define Move_amt_per_tickle @implementation Happygesturerecognizer-(void) Touchesbegan: (Nsset *) touches Witheve 
  NT: (Uievent *) event {Uitouch * touch = [touches anyobject]; 
Self.curticklestart = [Touch LocationInView:self.view]; }-(void) touchesmoved: (Nsset *) touches withevent: (Uievent *) event {//Make sure we ' ve moved a minimum amount s 
  Ince Curticklestart Uitouch * touch = [touches anyobject]; 
  Cgpoint ticklepoint = [Touch LocationInView:self.view]; 
  CGFloat Moveamt = ticklepoint.x-self.curticklestart.x; 
  Direction curdirection; 
  if (Moveamt < 0) {curdirection = Directionleft; 
  else {curdirection = Directionright; 
   
  } if (ABS (Moveamt) < move_amt_per_tickle) return; 
    The confirmation direction changed if (self.lastdirection = = Directionunknown | | (self.lastdirection = = Directionleft && Curdirection = = Directionright) | | (self.lastdirection = = Directionright && curdirection = = directionleft)) 
    {//Tickle times self.ticklecount++; 
    Self.curticklestart = Ticklepoint; 
     
    Self.lastdirection = curdirection; 
    The callback function is invoked once the number of scratches is more than specified, and the gesture is set to the end state//. if (self.state = = uigesturerecognizerstatepossible && self.ticklecount > Required_tickles) {[Self setst 
    Ate:uigesturerecognizerstateended]; 
  }}-(void) Reset {self.ticklecount = 0; 
  Self.curticklestart = Cgpointzero; 
  Self.lastdirection = Directionunknown; 
  if (self.state = = uigesturerecognizerstatepossible) {[Self setstate:uigesturerecognizerstatefailed]; 
}-(void) touchesended: (Nsset *) touches withevent: (Uievent *) event {[Self reset]; 
}-(void) touchescancelled: (Nsset *) touches withevent: (Uievent *) event {[Self reset]; 
 } @end

Call the custom gesture as above, and go back to writing like this:

-(void) Handlehappy: (Happygesturerecognizer *) recognizer{ 
  [Self.heheplayer play]; 

After the success of the gesture to play lol sound.

Run on the real machine, hold down a view, drag around quickly, it will make a laugh.

Code resolution:

Get start coordinates first: Curticklestart

The current drop is left or right by contrast to the X value of the Ticklepoint. Calculate whether the value of the moved X is greater than the move_amt_per_tickle distance, and if so, return.

Then judge whether there are three moves in different directions, and if so, the gesture ends and the callback.

Source code: Source code download.

The above is the entire content of this article, I hope to help you learn, but also hope that we support the cloud habitat community.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.