2013-05-04 9 views
0

주 뷰에 2 차원 단추 배열이 있으며이 뷰 내에서 끌어서 이동할 수 있기를 원합니다. 버튼은 약 23x23 픽셀로 매우 좁습니다. 제어 이벤트 touchDragExittouchDragOutside에 대한 대상을 추가했지만 단추 밖으로 손가락을 움직여 많은 픽셀이 발사되었습니다. 그러므로 나는 UIButton을 서브 클래 싱했고 continueTrackingWithTouch을 오버 플로우 했으므로 SO에서 찾은 일부 코드를 사용했다. 슈퍼 클래스 구현을 호출하지 않습니다.UIControlEventTouchDragOutside 구현의 문제

-(BOOL)continueTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event 
{ 
    CGFloat boundsExtension = 5.0f; 
    CGRect outerBounds = CGRectInset(self.bounds, -1 * boundsExtension, -1 * boundsExtension); 

    BOOL touchOutside = !CGRectContainsPoint(outerBounds, [touch locationInView:self]); 
    if(touchOutside) 
    { 
     BOOL previousTouchInside = CGRectContainsPoint(outerBounds, [touch previousLocationInView:self]); 
     if(previousTouchInside) 
     { 
      [self sendActionsForControlEvents:UIControlEventTouchDragExit]; 
     } 
     else 
     { 
      [self sendActionsForControlEvents:UIControlEventTouchDragOutside]; 
     } 
    } 
    return self.tracking; 
} 

두 이벤트가 올바르게 해고하지만 내 UIControlEventTouchDragOutside 조치는 그 조치라고 잘못 터치 정보를 수신합니다. 내가 많이 떨어져 버튼에서 손가락을 이동시킬 때까지

-(void) dragOutside:(UIButton *) sender withEvents:(UIEvent *) event 
{ 
    UITouch *touch = [[event allTouches] anyObject]; 
    CGPoint relativeLocToInitialCell = [touch locationInView:sender]; 

    NSLog(@"Translation %f %f NumTouch %d",relativeLocToInitialCell.x, relativeLocToInitialCell.y, [[event allTouches] count]); 
    ... 
} 

[[event allTouches] count] 여전히 0을 반환 : 여기 내 구현의 첫 번째 부분입니다. 물론 relativeLocToInitialCell 필드 인 xy은 모두 0이며, 이는 나중에 계산에 사용하는 값입니다. 어떤 아이디어가 문제 일 수 있습니까?

편집 : 삭제 된 답변은 touchdrag 이벤트 대신 UIPanGestureRecognizer을 사용하는 것이 좋지만 한 이벤트를 처리하기 전에 너무 빨리 발사했기 때문에 사용할 수 없습니다. 다른 이벤트가 하나 더 있습니다.

답변

3

나는 또한 UIControlEventTouchDragInside 이벤트를 처리해야했습니다. 이 방법으로 해결할 수 있지만 이러한 터치 드래그 이벤트의 기본 원리를 생각하면 합리적인 해결책이됩니다. 모든 드래그 이벤트는 touchesBegan, touchesMoved and touchesEnded에서 제공됩니다. Apple은 UIControlEventTouchDragOutside이 전송되기 전에 일부 임계 값을 추가했지만 그 임계 값 UIControlEventTouchDragInside 이벤트가 확실히 전송 될 때까지 올라갔습니다.

내 솔루션은 재정의 된 continueTrackingWithTouch 메서드를 제거하고 기본 구현을 계속 진행했습니다. 그런 다음 내부 및 외부 이벤트를 처리하고 종료 코드에서 내부 이벤트로 초기화 코드를 이동하고 내부 이벤트에 제어문을 추가했습니다. 추상화 된 코드는 다음과 같습니다.

-(void) dragInside:(UIButton *) sender withEvents:(UIEvent *) event 
{ 
    if(stillInsideOriginalControl) return; 

    UITouch *touch = [[event allTouches] anyObject]; 
    CGPoint relativeLocToInitialCell = [touch locationInView:sender]; 

    [self processTouch]; 
} 

-(void) dragOutside:(UIButton *) sender withEvents:(UIEvent *) event 
{ 
    UITouch *touch = [[event allTouches] anyObject]; 
    CGPoint relativeLocToInitialCell = [touch locationInView:sender]; 

    [self processTouch]; 
}