custom iOS gesture

前端 未结 2 1154
孤街浪徒
孤街浪徒 2021-02-06 18:52

I am new to iOS/objective-C and I wanted to know how to build custom gestures. In particular, if a user taps the top right of the screen and slides his/her finger down the edge

2条回答
  •  遥遥无期
    2021-02-06 19:34

    Creating a UIGestureRecognizer subclass is a bit involved to do in a solid way. I very much recommend watching the WWDC2010 videos on the subject Session 120 - Simplifying Touch Event Handling with Gesture Recognizers & Session 121 - Advanced Gesture Recognition. They are thorough and well done.

    But for a very simple example, based on your question, I created a very simple gesture recognizer that fires when a user touches the upper left quadrant of the attached view and slides their finger down to the lower right quadrant of the attached view and picks up their finger, without sliding to the left side of the attached view.

    RightSlidedown.h:

    #import  // This import is essential
    @interface RightSlidedown : UIGestureRecognizer
    @end
    

    RightSlidedown.m

    #import "RightSlidedown.h"
    @implementation RightSlidedown
    -(id)initWithTarget:(id)target action:(SEL)action{
        if ((self = [super initWithTarget:target action:action])){
            // so simple there's no setup
        }
        return self;
    }
    -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
        UITouch *touch = [touches anyObject];
        if ([touch locationInView:self.view].x < CGRectGetMidX(self.view.bounds)) self.state = UIGestureRecognizerStateFailed;
        else if ([touch locationInView:self.view].y > CGRectGetMidY(self.view.bounds)) self.state = UIGestureRecognizerStateFailed;
    }
    -(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
        UITouch *touch = [touches anyObject];
        if([touch locationInView:self.view].x < CGRectGetMidX(self.view.bounds)) self.state = UIGestureRecognizerStateFailed;
    }
    -(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
        UITouch *touch = [touches anyObject];
        if ([touch locationInView:self.view].x < CGRectGetMidX(self.view.bounds)) self.state = UIGestureRecognizerStateFailed;
        else if ([touch locationInView:self.view].y < CGRectGetMidY(self.view.bounds)) self.state = UIGestureRecognizerStateFailed;
        else {
                // setting the state to recognized fires the target/action pair of the recognizer
            self.state = UIGestureRecognizerStateRecognized; 
        }
    }
    -(void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event{
        self.state = UIGestureRecognizerStateCancelled;
    }
    -(void)reset{
        // so simple there's no reset
    }
    @end
    

    So basically the gesture recognizer gets what seems like the standard touch events. (They're not, but they act that way). As you respond to the movements you change the state property of your gesture recognizer.

    There are two basic types of recognizers, "Discrete" (think tap gesture) and "Continuous" (think pan gesture). Both types automatically start in UIGestureRecognizerStatePossible in the beginning.

    For a "Discrete" type, like this one, your goal is to get to state UIGestureRecognizerStateRecognized or UIGestureRecognizerStateFailed as soon as possible.

    The ideal usage of this example would be to add the RightSlidedown gesture recognizer to the main view of a new "Single View Application" in the view controller's viewDidLoad.

    [self.view addGestureRecognizer:[[RightSlidedown alloc] initWithTarget:self action:@selector(rightSlide:)]];
    

    Then a simple action method is all that's required, like so:

    -(void)rightSlide:(RightSlidedown *)rsd{
        NSLog(@"right slide");
    }
    

提交回复
热议问题