在拖动时没有在嵌套视图上调用NSView mouseEntered - 是黑客唯一的选择吗?

时间:2017-02-27 19:21:18

标签: cocoa mouseevent drag nsview

我有一个带有嵌套NSView的NSView,如果我没有使用NSTracking区域拖动鼠标事件在所有子视图上触发......很好。

但是当我从父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

2 个答案:

答案 0 :(得分:1)

正如Handling Mouse Dragging Operations中所述,有两种方法可以实现拖动。您的解决方案会短路应用程序的正常事件循环,您必须致电mouseEntered:mouseExited:。如果您不想这样做,请实施具有其他缺点的三种方法。

答案 1 :(得分: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