2011-09-17 3 views
4

NSView 안에 MyView (서브 클래스는 NSView)의 여러 뷰가 있습니다. MyView-mouseEntered:, -mouseExited:, -mouseDown:, -mouseDragged:-mouseUp:을 구현합니다.mouseDragged 이벤트가 다른보기에 의해 도난당했습니다.

MyView이 마우스 다운 이벤트를 수신하면 거의 모든 마우스 끌기 이벤트는 다음 마우스 업 이벤트까지 MyView까지 수신됩니다. 커서가 MyView 외부로 나가더라도. 그것이 예상되는 행동입니다.

간혹 MyView은 마우스 다운 이벤트를 수신하지만 커서가 MyView 내부에있는 동안 마우스 끌기 및 마우스 업 이벤트 만 수신합니다. 커서가 다른 MyView으로 이동하면 MyView은 마우스 드래그 이벤트 (처음 마우스 다운 이벤트를 수신하지 않고)를 수신하기 시작하며 후속 마우스 업 이벤트를 수신 할 수 있습니다.

경우는 마우스 다운 이벤트가 MyView의 상단에 FooView (NSView의 서브 클래스)를 작성, 중요하고, 마우스 드래그 이벤트는 FooView의 프레임 크기를 조정합니다. 이것은 FooView 중 하나가 생성 된 후에 만 ​​문제를 재현 할 수 있기 때문에 관련 될 수 있습니다. FooView은 마우스 이벤트 메소드를 구현하지 않습니다.

나는 잠시 동안이 문제에 얽혀 있었고, 단순한 예제에서 의도적으로 문제를 재현하거나 문제를 재현하지 못했습니다. 내 코드에 대해 궁금한 점에 대해 기꺼이 대답 해 드리겠습니다. 게시물의 관련 부분이 무엇인지 확신 할 수 없습니다.

답변

2

확실하지 않음 (이 코코아 동작은 나에게 일치하지 않는 것) ...하지만 여기에 한 가지 가능한 해결 방법의 다음 MyView 인스턴스를 추적하는 인스턴스 변수를 만듭니다 수퍼에서

  1. 여기서 -mouseDown:이 발생했습니다.
  2. self에서 작동하는 대신 -mouseDragged:MyView 인 경우 수퍼 뷰에 저장된 MyView 인스턴스 참조에서 작동하십시오.

... 그러면 자신의 이벤트 루프를 실행하지 않고도 드래그중인 개체를 일관되게 추적 할 수 있습니다.

+0

문제의 원인은 예상 할 수있는 방법으로 형제의보기가 겹치는 것을 다루지 않는 NSView 인 것으로 밝혀졌다. 해결 방법으로 문제가 해결되었습니다 - 감사합니다. – jlstrecker

+0

고마워요,이 대답은 저에게 두통의 시간을 절약 해주었습니다! – DrRocket

+0

드래그하는 동안 MyView의 하위 항목이 커서 아래에서 사라지거나 (크기가 바뀌거나 크기가 조정 됨으로써) 사라지면 상황이 매우 빠르게 시작됩니다. –

0

마우스가 올라올 때까지 뷰에서 자신의 마우스 추적 루프를 실행해야합니다. nextEventMatchingMask :로 전달하여 더 많은 유형의 이벤트를 처리하도록 확장 할 수 있습니다. 루트 문제가 무엇인지

- (void)mouseDown:(NSEvent*)event 
{ 
    CGPoint hitPoint = [self pointInViewSpaceFromEvent:event]; 

    BOOL isDragging = NO; 
    BOOL isTracking = YES; 

    while (isTracking) 
    {  
     switch ([event type]) 
     { 
      case NSLeftMouseDown: 
       [self singleMouseDownAtPoint:hitPoint withModifierFlags:[event modifierFlags]]; 
       break; 

      case NSLeftMouseUp: 
       isTracking = NO; 
       if (isDragging) 
        [self mouseDraggingDidEndAtPoint:hitPoint]; 
       else 
        [self singleMouseUpAtPoint:hitPoint withEvent:event]; 
       break; 

      case NSLeftMouseDragged: 
       if (isDragging) 
        [self mouseDraggingAtPoint:hitPoint withModifierFlags:[event modifierFlags]]; 
       else 
        isDragging = YES; 
       break; 
      default: 
       break; 
     } 

     if (isTracking) 
     { 
      event = [[self window] nextEventMatchingMask:NSLeftMouseDraggedMask | NSLeftMouseUpMask]; 
      hitPoint = [self pointInViewSpaceFromEvent:event]; 
     } 
    } 
} 
+0

감사합니다. 이것은 정확하게 문제를 해결하지는 않지만 단서를 제공합니다. 마우스 추적 루프가 실행 중일 때 드래그 및 마우스 업 이벤트는 도난 당하지 않습니다. 아마도 다른 'MyView'가 수신을 차단했기 때문에 이벤트를 훔칠 다른 'MyView'가 없기 때문입니다 이벤트. 그러나 마우스 트랙킹 루프가 다른 모든 이벤트를 차단하기 때문에 * 나를 위해 작동한다고 생각하지 않습니다. 다른'MyView'에 대한 이벤트와 애플리케이션의 다른 객체는 통과해야합니다. 나는 'dispatch_async'에서 루프를 래핑하려고 시도했지만, 다시 한 번 드래그 앤 마우스 업 이벤트가 도난당했습니다. – jlstrecker

+0

보기에서 이벤트를 드래그하여 처리해야하는 경우이를 수행하는 유일한 올바른 방법입니다. 이것은 모든 코코아 컨트롤이 작동하는 방식입니다. NSSlider의 손잡이를 드래그하십시오.자체 루프에서 마우스를 추적하지 못하면 커서가 경계에서 벗어나 자마자 끌기 이벤트에 응답하지 않습니다. 네, nextEventMatchingMask에 지정한 유형의 모든 이벤트는이 특정보기로 이동하고 다른보기는 수신하지 않습니다. 그러나 이것이 필요한 것은 아닙니다. 뷰 사이에 드래그를 처리하려면 한 수준 위로 수행해야합니다. int 해당 뷰의 슈퍼 뷰입니다. – Davyd

+0

"이것이 유일한 유일한 방법"이라는 의미는 무엇입니까? Apple 문서가 완벽하지는 않지만 [Cocoa Event-Handling Guide] (http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/EventOverview/HandlingMouseEvents/HandlingMouseEvents.html#//apple_ref/ doc/uid/10000060i-CH6)는'mouseDragged'와'mouseUp'가 작동해야 함을 암시하는 것으로 보입니다. 내 문제는 애플 코드에 버그가 있는가, 아니면 어떻게 사용하는 지 내 자신의 오해인가? 'mouseDragged'와'mouseUp' *는 보통 예상대로 작동합니다. – jlstrecker

관련 문제