Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UILongPressGestureRecognizer stop handle without stop touching

I'm using UILongPressGestureRecognizer class to handle if one item is being selected.

The logic is as follows: User press during 1 second an item (UIView subclass). Once the gesture is detected, the item is highlighted and moveable.

The user must move this item across the screen without stop touching it.

The problem I'm facing is the gesture recognized shadows touchesBegan/Move/Ended necessary for the item class to arrange the movement.

I tried to remove the gesture recognized once is detected and the item selected. But still sending messages to the handle of gesture instead of call touches methods.

Anyone knows any way to stop "listening" the gesture recognizer without leave the finger of the screen?

Thanks.

Here the code:

-(void)addGestures
{
    UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc]
                                               initWithTarget:self 
                                               action:@selector(handleLongPress:)];
    longPress.minimumPressDuration = iItemLongPressTime;
    [self addGestureRecognizer:longPress];
    [longPress release];
}
- (void)handleLongPress:(UILongPressGestureRecognizer*)sender { 
    if (sender.state == UIGestureRecognizerStateEnded) {

        NSLog(@"Long press Ended");
    }
    else {
        if (self.isSelected) return;

        if ([delegate respondsToSelector:@selector(singleTouch:)])
            [delegate singleTouch:self];

        [self removeGestureRecognizer:[self.gestureRecognizers objectAtIndex:0]];

        NSLog(@"Long press detected.");
    }
}

As you can see in the else branch the delegate calls enables all procedures to mark this item as selected, and just after remove the recognizers.

What I'm missing?

--EDIT--

Done! This works:

#pragma mark Gesture Functions
-(void)addGestures
{
    UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc]
                                               initWithTarget:self 
                                               action:@selector(handleLongPress:)];
    longPress.minimumPressDuration = iItemLongPressTime;
    [self addGestureRecognizer:longPress];
    [longPress release];
}
- (void)handleLongPress:(UILongPressGestureRecognizer*)sender { 
    if (sender.state == UIGestureRecognizerStateEnded) {

        NSLog(@"Long press Ended");
    }
    else {
        NSLog(@"Long press detected.");

        if (self.isSelected) return;

        if ([delegate respondsToSelector:@selector(singleTouch:)])
            [delegate singleTouch:self];

        [sender removeTarget:self action:@selector(handleLongPress:)];
        sender.enabled = NO;
        [self removeGestureRecognizer:sender];



    }
}

Regards!

like image 731
NemeSys Avatar asked Mar 13 '12 16:03

NemeSys


2 Answers

Does the custom UIView class have its own touch handling code? If not, a simple solution is to set the allowableMovement property of the UILongPressGestureRecognizer to CGFLOAT_MAX, or some big number, and use the gesture update callbacks to drag your custom view around. You can get the displacement using the - (CGPoint)locationInView:(UIView *)view method on the superview, and compare its position to when the recognizer began.

like image 83
Tark Avatar answered Oct 21 '22 13:10

Tark


There are two solutions in my mind.

  1. For animating uiview, please wrote a new class which is inherited from the UIView class and implement the touch delegates instead of writing the Gustures to handle animation(if the touch delegates are not triggering in the current class).

2.I have successfully removed the UILongPressGestureRecognizer after triggered it once.

Please refer the below code .ask me if you have any queries

Steps I have Done

I have added a UIView as "myView" to my main-view when main-view loads.

I have given the Tag to the myView (you can give 1,2,3…etc) to differentiate the tapped view from the main-view subviews.

Assigned the UILongPressGestureRecognizer gesture to myView and assigned target as "moveMe" method.

When user Pressed the myView long, the "moveMe" method will trigger.

Then I iterated the mainView Subviews with the condition Tag == 1

I have removed the UILongPressGestureRecognizer from the subview.As we can know that Tagged 1 main-view subView is myView.

So the NSLog(@"gesture removed"); and NSLog(@"moveMe"); will log in console only at one time.

The NSLog(@"touchesBegan"); will trigger first instead of triggering the "moveMe" method.

Then NSLog(@"touchesBegan"); will trigger always after removed the gesture . "moveMe" method will not trigger ever.

Code

    - (void)viewDidLoad {    
        //Adding to UIView to main view when application is loading.
         UIView *myView = [[UIView alloc] initWithFrame:CGRectMake(20, 20, 80, 80)];        
         myView.backgroundColor = [UIColor viewFlipsideBackgroundColor];
          myView.tag = 1; //adding a tag to identify it.
        //Adding Long Press Gesture to the UIView.
        UILongPressGestureRecognizer *myGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(moveMe:)];
        [myView addGestureRecognizer:myGesture];
        [myGesture release];
        myGesture = nil;   
       [self.view addSubview:myView];   
       [myView release];
        myView = nil;    
        [super viewDidLoad];
    }    

    //Method to trigger when user pressed long on the added UIView.

 -(void)moveMe:(id)sender
 { 
      for (UIView *subViews in [self.view subviews]) 
      { 
            if (subViews.tag == 1) { 
                 [subViews removeGestureRecognizer:sender];
                 NSLog(@"gesture removed");
             }    
         }    
         NSLog(@"moveMe");
    }    
 -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
 {
     NSLog(@"touchesBegan");
 }

or please refer Disable gesture recognizer iOS

like image 45
Shamsudheen TK Avatar answered Oct 21 '22 14:10

Shamsudheen TK