自定义iOS手势

时间:2012-02-19 01:06:24

标签: objective-c ios uigesturerecognizer

我是iOS / objective-C的新手,我想知道如何构建自定义手势。特别地,如果用户轻敲屏幕的右上方并将他/她的手指沿着设备的边缘向下滑动到底部(左手侧的相同手势)。我读完了这个:

https://developer.apple.com/library/ios/#documentation/EventHandling/Conceptual/EventHandlingiPhoneOS/GestureRecognizers/GestureRecognizers.html#//apple_ref/doc/uid/TP40009541-CH6-SW2

但我想我无法弄清楚如何将其应用于我的具体案例。

2 个答案:

答案 0 :(得分:6)

创建一个UIGestureRecognizer子类有点可靠。我非常推荐观看主题为Session 120 - Simplifying Touch Event Handling with Gesture Recognizers&的WWDC2010视频。 Session 121 - Advanced Gesture Recognition。他们彻底而且做得很好。

但是对于一个非常简单的例子,基于你的问题,我创建了一个非常简单的手势识别器,当用户触摸附加视图的左上象限并将其手指向下滑动到附加视图的右下象限时触发然后拿起他们的手指,而不会滑动到所附视图的左侧。

RightSlidedown.h:

#import <UIKit/UIGestureRecognizerSubclass.h> // 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

所以基本上手势识别器会获得看似标准的触摸事件。 (他们不是,但他们这样做)。当您回复动作时,您可以更改手势识别器的state属性。

有两种基本类型的识别器,&#34; Discrete&#34; (想想点击手势)和&#34;连续&#34; (想想泛手势)。这两种类型都会在开始时自动从UIGestureRecognizerStatePossible开始。

对于&#34; Discrete&#34;类似于此类型,您的目标是尽快转到州UIGestureRecognizerStateRecognizedUIGestureRecognizerStateFailed

此示例的理想用法是将RightSlidedown手势识别器添加到新的&#34;单一视图应用程序&#34;的主视图中。在视图控制器viewDidLoad中。

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

然后需要一个简单的动作方法,如下所示:

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

答案 1 :(得分:1)

您可以通过在触摸的x和y轴上看到正或负delta来实现。例如,复选标记手势(√)将为负增量,后跟y中的正增量,而x始终为负增量,触摸结束的高度低于其开始时的高度。添加更多手指即可添加更多支票。

伪代码:

bool firstStroke, secondStroke, motion, override;
while (touchdown){
if (yDelta < 0){firstStroke = TRUE;}
if (firstStroke && yDelta > 0){secondStroke = TRUE;}
if (xDelta < 0){motion = TRUE;}
if (xDelta > 0 || (firstStroke && secondStroke && yDelta < 0)){override = TRUE;}
}
if (firstStroke && secondStroke && motion && start.y > end.y && !override){
    return TRUE;
}else{
    return FALSE;
}

while命令意味着触摸失败时,检查3件事:

- 如果触摸向下移动

- 如果触摸向下移动后再次向上移动

- 如果触摸从右向左移动

第四项检查是查看触摸是否从左向右移动,或者是否在手势完成后手势向下移动。

触摸完成后,还有一个检查,看看手势是否正确移动,点是否在正确的位置开始和结束,以及手势是否以不正确的动作移动(覆盖)。

希望有所帮助。