UIPanGestureRecognizer停止调用选择器

时间:2013-02-13 18:51:13

标签: ios objective-c uigesturerecognizer uipangesturerecognizer

我无法使用UIPanGestureRecognizer,因为它只是在我的手指移动时调用选择器,我希望它能够继续调用选择器,即使我的手指站在同一个地方。

屏幕上有4个物体,一个在顶部,一个在右侧,一个在左侧,一个在底部。我在屏幕的中心有一个对象(这是我用panGesture移动的对象)。当这个物体接触到其他物体时,我希望它给我一个日志,当它接触时它会起作用,但是如果我把手指放在同一个地方它停下来给我记录,如果我移动一点,它就会再次开始给我记录。

无论如何,即使我的手指放在同一个地方,我仍可以继续拨打选择器吗?

这是一个代码示例:

- (void)moveObject:(UIPanGestureRecognizer *)sender
{
    CGPoint translation = [sender translationInView:self.limiteDirecional];
    [sender setTranslation:CGPointMake(0, 0) inView:self.limiteDirecional];

    CGPoint center = sender.view.center;
    center.y += translation.y;
    int yMin = 0;
    int yMax = self.limiteDirecional.frame.size.height;

    if (center.y < yMin || center.y > yMax )
        return;

    sender.view.center = center;

    center.x += translation.x;
    int xMin = self.limiteDirecional.frame.size.width;
    int xMax = 0;

    if (center.x > xMin || center.x < xMax)
        return;

    sender.view.center = center;

    if (CGRectIntersectsRect(sender.view.frame,self.Top.frame)) {
         NSLog(@"TOP");        
    }

    if (CGRectIntersectsRect(sender.view.frame,self.Botton.frame)) {
        NSLog(@"BOTTON");
    }

    if (CGRectIntersectsRect(sender.view.frame,self.Right.frame)) {
        NSLog(@"RIGHT");
    }

    if (CGRectIntersectsRect(sender.view.frame,self.Left.frame)) {
        NSLog(@" LEFT");
    }

    if (sender.state == UIGestureRecognizerStateEnded) {
        sender.view.center = CGPointMake(self.view.frame.size.width / 2, self.view.frame.size.height / 2);
    }
}

1 个答案:

答案 0 :(得分:3)

我并不完全遵循您的例行程序的逻辑,因此我将提供一个通用模板,说明当您想要在手势中间连续事件时,解决方案可能是什么样的,无论用户是移动手指还是不。希望您可以根据自己的需要调整此技术。

这使用CADisplayLink,与使用NSTimer的旧技术相比,它被认为是更好的动画技术。但是,要使用CADisplayLink,您需要add the needed framework,QuartzCore.framework,如果您还没有。另请注意,在我的手势识别器中,我正在检查手势的状态,以确定我们是在一个手势中,一个手势中,还是一个手势:

#import "ViewController.h"
#import <QuartzCore/QuartzCore.h>

@interface ViewController ()

@property (nonatomic, strong) CADisplayLink *displayLink;
@property (nonatomic) CGPoint translationInView;

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    UIPanGestureRecognizer *gesture = [[UIPanGestureRecognizer alloc] initWithTarget:self
                                                                              action:@selector(handleGesture:)];
    // I'm adding to the main view, but add it to whatever you want
    [self.view addGestureRecognizer:gesture]; 
}

- (void)startDisplayLink
{
    self.displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(handleDisplayLink:)];
    [self.displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
}

- (void)stopDisplayLink
{
    [self.displayLink invalidate];
    self.displayLink = nil;
}

- (void)handleDisplayLink:(CADisplayLink *)displayLink
{
    NSLog(@"%s translationInView = %@", __FUNCTION__, NSStringFromCGPoint(self.translationInView));

    // Do here whatever you need to happen continuously while the user is in the
    // middle of the gesture, whether their finger is moving or not.
}

- (void)handleGesture:(UIPanGestureRecognizer *)gesture
{
    self.translationInView = [gesture translationInView:gesture.view];

    if (gesture.state == UIGestureRecognizerStateBegan)
    {
        [self startDisplayLink];

        // Do whatever other initialization stuff as the user starts the gesture
        // (e.g. you might alter the appearance of the joystick to provide some
        // visual feedback that they're controlling the joystick).
    }
    else if (gesture.state == UIGestureRecognizerStateChanged)
    {
        // Do here only that stuff that actually changes as the user is moving their
        // finger in the middle of the gesture, but which you don't need to have
        // repeatedly done while the user's finger is not moving (e.g. maybe the
        // visual movement of the "joystick" control on the screen).
    }
    else if (gesture.state == UIGestureRecognizerStateEnded ||
             gesture.state == UIGestureRecognizerStateCancelled ||
             gesture.state == UIGestureRecognizerStateFailed)
    {
        [self stopDisplayLink];

        // Do whatever other cleanup you want to do when the user stops the gesture
        // (e.g. maybe animating the moving of the joystick back to the center).
    }
}
@end

如果您使用NSTimer,也可以获得类似的效果。无论什么对你有用。