2017-02-27 21 views
1

我有一個NSView的嵌套NSView的,如果我不拖動鼠標事件觸發所有子視圖使用NSTracking區域...罰款。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

也許問題可能與你繼承的方式。 你在重寫的類方法中調用超級方法嗎? 您是否正在對某個特定的預先存在的控件進行分區,或者是否立即從NSView中進行分區? 你有沒有在XCode中發出任何警告?

編輯:

嗨, 我被打了一下,像你這樣一個簡單的事情。

你看過CableView子類中的hitTest:override嗎?也許它應該以不同的方式返回: return self == hitView?自我:無;

這是我傻實施視圖子的同時拖動繪製一個指南:

#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的子類,而不是調用超類,你能看到dropbox項目嗎? – Chris

+0

嗨,也許問題可能與您的一些意見不傳播到下一個響應mouseDown:事件。你有沒有試圖在你的重寫方法的邏輯中的某些點調用[super mouseDown:event]? – valeCocoa