我有一个带有嵌套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
答案 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