2017-02-27 10 views
1

Nestracking area ...를 사용하는 모든 하위 뷰에서 마우스 이벤트를 끌지 않으면 중첩 된 NSView가있는 NSView가 있습니다.드래그하는 동안 중첩 된 뷰에서 NSView mouseEntered가 호출되지 않습니다. 해킹 만 가능한 옵션입니까?

자식 NSView를 통해 부모 NSView에서 드래그하면 마우스 이벤트가 실행되지 않고 이벤트에 응답하도록하는 방식 만 해킹으로 표시되어 더티 느낌이납니다. 그들이 당신이 그것을두면

NSView *hit = [self findViewUnderPoint:loc]; 
if (hit != nil) 
{ 
    if (hit != last) 
    { 
     [last mouseExited:event]; // This looks terrible to me 
    } else { 
     [hit mouseEntered:event]; // This looks terrible to me 
    } 
    last = hit; 
} 

당신은 위의 코드 주석 경우

는 하위 뷰 이벤트는 트리거되지 않습니다 ...하지만 내가 직접 전화 드렸습니다.

어떻게 작동하는지 먼저 보여준 다음 드래그하여 (해킹으로) 내 비디오를 업로드했습니다 - 내 소스 코드도 포함 시켰습니다. 아마 문제가 당신이 서브 클래스 화하는 방식과 관련이있을 수있는이

https://www.dropbox.com/s/b6ps8tz0jvg2gwy/Designable.zip?dl=0

+0

NSTrackingEnabledDuringMouseDrag를 사용하고 있습니까? – Ssswift

+0

이름 : 귀하의 dropbox.com 링크가 나를 위해 작동하지 않습니다. – Ssswift

+0

@Ssswift - 예 NSTrackingEnabledDuringMouseDrag가 사용됩니다. – Chris

답변

1

바와 같이 Handling Mouse Dragging Operations 설명은, 드래그 구현하는 두 가지 방법이있다. 솔루션은 응용 프로그램의 일반 이벤트 루프를 단락시키고 mouseEntered:mouseExited:에 전화해야합니다. 이 작업을 수행하지 않으려면 다른 단점이있는 세 가지 방법 접근 방식을 구현하십시오.

+0

세 가지 방법의 단점에 어떤 빛이 퍼질 수 있습니까? – Chris

+0

"그러나이 기술은 더 많은 코드와 인스턴스 변수를 요구할 수 있습니다." [DragItemAround] (https://developer.apple.com/library/content/samplecode/DragItemAround/Introduction/Intro.html#//apple_ref/doc/uid/DTS10003900) 샘플 코드는 두 가지 방법을 보여줍니다. – Willeke

0

을하는

나는 "올바른 방법"다음에 이상적입니다. 재정의 한 클래스 메서드에서 super 메서드를 호출하고 있습니까? NSView에서 특정 기존 컨트롤을 서브 클래 싱하고 있습니까? Xcode에서 경고 메시지가 표시됩니까?

편집 :

안녕, 내가 당신처럼 간단한 일이있는 비트를 연주했다.

CableView 하위 클래스에서 hitTest : override를 보았습니까? 어쩌면 다르게 반환해야합니다 : return self == hitView? 자기 : nil;

이 드래그하는 동안 가이드를 그리는 뷰의 서브 클래스의 내 바보 구현 :

#import "MYSimpleScratchPad.h" 

@implementation MYSimpleScratchPad 
{ 
    NSPoint start; 
    NSPoint finish; 
    BOOL dragging; 
} 

- (instancetype)initWithFrame:(NSRect)frameRect { 
    self = [super initWithFrame:frameRect]; 
    if (self) { 
     _path = [NSBezierPath bezierPath]; 
     dragging = NO; 
    } 
    return self; 
} 

- (void)drawRect:(NSRect)dirtyRect { 
    [super drawRect:dirtyRect]; 

    [[NSColor redColor] set]; 
    [_path removeAllPoints]; 
    if (dragging) { 
     [_path setLineWidth:5.0]; 
     [_path setLineCapStyle:NSRoundLineCapStyle]; 
     [_path moveToPoint:start]; 
     [_path lineToPoint:finish]; 
     [_path stroke]; 
    } 

} 

- (void)mouseDown:(NSEvent *)event { 
    start = [event locationInWindow]; 
    NSRect theFrame = [self frame]; 
    start.x -= theFrame.origin.x; 
    start.y -= theFrame.origin.y; 
    _path = [NSBezierPath bezierPath]; 
} 

- (void)mouseDragged:(NSEvent *)event { 
    finish = [event locationInWindow]; 
    NSRect theFrame = [self frame]; 
    finish.x -= theFrame.origin.x; 
    finish.y -= theFrame.origin.y; 
    dragging = YES; 
    [self setNeedsDisplay:YES]; 
} 

- (void)mouseUp:(NSEvent *)event { 
    start = NSMakePoint(0.0, 0.0); 
    finish = NSMakePoint(0.0, 0.0); 
    dragging = NO; 
    [self setNeedsDisplay:YES]; 
} 

- (NSView *)hitTest:(NSPoint)point { 
    NSView *hitView = [super hitTest:point]; 
    return self == hitView ? self:nil; 
} 

@end 
+0

안녕하세요, 그 문제에 대한 Xcode에 경고가 없습니다. NSView를 직접 서브 클래스로 분류하고 있으며, 슈퍼를 호출하지 않습니다. 드롭 박스 프로젝트를 볼 수 있습니까? – Chris

+0

안녕하세요, 문제가 nextResponder mouseDown : 이벤트로 전달되지 않는 일부보기와 관련 될 수 있습니다. 재정의 된 메소드의 로직에서 특정 지점에서 [super mouseDown : event]를 호출하려고 시도 했습니까? – valeCocoa