2012-03-13 6 views
6

하나의 항목이 선택되면 UILongPressGestureRecognizer 클래스를 사용하여 처리하고 있습니다.UILongPressGestureRecognizer 멈추지 않고 손을 멈춤

논리는 다음과 같습니다. 사용자가 1 초 동안 항목을 누릅니다 (UIView 하위 클래스). 제스처가 감지되면 해당 항목이 강조 표시되고 움직일 수 있습니다.

사용자는 터치하지 않고이 항목을 화면에서 이동해야합니다.

내가 직면하고있는 문제는 그림자를 인식 한 제스처입니다 .Began/Move/Moveed/Move/Ended는 항목 클래스가 동작을 정렬하는 데 필요합니다.

한 번 감지 된 항목과 선택한 항목을 제거하려고했습니다. 그러나 여전히 전화 접촉 대신 제스처 핸들에 메시지를 보냅니다.

누구나 화면의 손가락을 떼지 않고도 제스처 인식기를 "듣고"멈추는 방법을 알고 있습니까?

감사합니다. 여기에 코드

:

-(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."); 
    } 
} 

대리자 선택으로이 항목을 표시하는 모든 절차를 가능하게 호출하는 다른 지점에서보고, 직후 인식기를 제거 할 수있다.

내가 무엇이 누락 되었습니까?

--EDIT--

완료! 작동 방식 :

#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]; 



    } 
} 

감사합니다.

답변

1

내 마음에는 두 가지 해결책이 있습니다.

  1. 는 UIView의 애니메이션의 경우, 대신 (터치 대표는 현재 클래스에서 트리거되지 않은 경우) 애니메이션을 처리 할 수 ​​Gustures을 쓰는 터치 대표를 UIView의 클래스에서 상속하고 구현하는 새로운 클래스를 작성하십시오.

2. 나는 UILongPressGestureRecognizer를 한 번 트리거 한 후에 성공적으로 제거했습니다. 당신은 내가

내가 내 주요보기에 "MYVIEW"로하여 UIView를 추가 완료 한

단계 어떤 쿼리

이있는 경우

아래의 코드가 저를 自問 해보십시오 참조하십시오 때 메인보기로드 .

주 뷰 서브 뷰와 탭 뷰를 구별하기 위해 myView (1,2,3 ... 등을 줄 수 있음)에 태그를 지정했습니다.

UILongPressGestureRecognizer 제스처를 myView에 지정하고 대상을 "moveMe"메서드로 지정했습니다.

사용자가 myView를 길게 누르면 "moveMe"메서드가 트리거됩니다.

그런 다음 우리가 태그 1 주 뷰 서브 뷰가 MYVIEW는 것을 알 수 나는 subview.As에서 UILongPressGestureRecognizer를 제거한 상태 태그 == 1

와 MAINVIEW 파단 반복.

NSLog (@ "제스처 제거됨"); 와 NSLog (@ "moveMe"); 콘솔에 한 번만 로그인합니다.

NSLog (@ "touchesBegan"); "moveMe"메소드를 트리거하는 대신에 먼저 트리거합니다.

NSLog (@ "touchesBegan"); 제스처를 제거한 후 항상 트리거됩니다. "moveMe"메소드는 결코 트리거되지 않습니다.

코드

- (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"); 
} 

또는 Disable gesture recognizer iOS

+0

질문에 대해 자세히 설명해주세요. –

+0

매개 변수로 발신자를 삭제하려고 시도했지만 여전히 작동하지 않았습니다. – NemeSys

+0

내 대답을 편집했습니다 ... –

4

사용자 정의 UIView의 클래스가 자신의 터치 처리 코드가 있습니까 참조하십시오? 그렇지 않은 경우 간단한 해결책은 UILongPressGestureRecognizerallowableMovement 속성을 CGFLOAT_MAX 또는 큰 숫자로 설정하고 제스처 업데이트 콜백을 사용하여 사용자 지정보기를 드래그하는 것입니다. 슈퍼 뷰에서 - (CGPoint)locationInView:(UIView *)view 메소드를 사용하여 위치 변경을 가져올 수 있으며 인식기가 시작된 위치와 위치를 비교할 수 있습니다.

+1

+1 이것은 가장 간단한 해결책입니다. 본질적으로, '제스처 인식기를 사용하는 경우 제스처 인식기를 사용하십시오.' – NJones

+1

'allowableMovement' 속성을 변경할 필요가 없습니다. 오류를 테스트하는 데만 사용됩니다. 'UILongPressGestureRecognizer.h'에있는 주석에서 "제스처가 실패하기 전에 허용되는 픽셀의 최대 움직임. 일단 인식되면 (minimumPressDuration 이후) 터치 추적의 나머지 동안 손가락 움직임에 제한이 없습니다." " – NJones

+0

안녕하세요, 답변 해 주셔서 감사합니다 . UIView 하위 클래스는 superview에서 크기 및 위치를 조작하기 위해 touchesBegan/Moved/Ended를 구현합니다. 제스처의 사용은 모든 항목을 다루기에 덜 민감하게 만들 필요가 있습니다. 지금은 제스처 인식기 객체를 비활성화하는 솔루션을 사용하고 있으며 매력처럼 작동합니다. – NemeSys

관련 문제