如果 Cocoa 应用程序正在跟踪 mouseEntered() 事件,则拖动事件未收到

Dragging Events Not Receiving If mouseEntered() Events Is Tracking by Cocoa App

正在开发 Cocoa 应用程序,该应用程序需要做两件事以防万一 - :

1) 鼠标进入或退出

2) 鼠标拖拽文件到应用

我有观点A, 视图 A 已注册以接收拖动事件,并且 具有用于接收鼠标进入和退出事件的跟踪区域,

问题是: 如果我将文件拖到视图 A;视图 A 接收 mouseEntered: 事件而不是 draggingEntered: 事件。

- (NSDragOperation)draggingEntered:(id < NSDraggingInfo >)sender
{
   NSLog(@"draggingEntered called");
}


- (void)mouseEntered:(NSEvent *)theEvent
{
   NSLog(@"mouseEntered called");
}

2018-02-05 14:08:58.273 XXX_APP [3420:119122] mouseEntered called

2018-02-05 14:08:58.273 XXX_APP [3420:119122] draggingEntered called

问题是每当我将文件拖到视图时;它进入 mouseEntered() 不要进入 mouseDragged()。 有什么解决方法吗?

提前致谢。

我可能错了,但我相信拖动操作取决于鼠标进入视图,因此如果您正在跟踪鼠标事件,mouseEntered: 方法将始终首先被调用。也就是说,您可以延迟对 mouseEntered: 事件执行某些操作,让视图有时间查看它是否跟随拖动操作,如果是,则取消 mouseEntered: 调用。这可以使用 performSelector:withObject:afterDelay:(使用用户可能不会注意到的非常短暂的延迟)和 cancelPreviousPerformRequestsWithTarget: 来完成,如下所示:

- (void)updateTrackingAreas {
    [super updateTrackingAreas];
    for (NSTrackingArea *trackingArea in self.trackingAreas) {
        [self removeTrackingArea:trackingArea];
    }
    [self addTrackingArea:[[NSTrackingArea alloc] initWithRect:self.bounds options:(NSTrackingMouseEnteredAndExited | NSTrackingActiveAlways) owner:self userInfo:nil]];
}

- (void)_mouseEntered:(NSEvent *)event {
    NSLog(@"mouseEntered");
    //do something...
}

- (void)mouseEntered:(NSEvent *)event {
    //pause 0.05 seconds before acting on this event,
    //giving the view time to see if a draggingEntered: event is triggered
    [self performSelector:@selector(_mouseEntered:) withObject:event afterDelay:0.05];
}

- (void)mouseExited:(NSEvent *)event {
    NSLog(@"mouseExited");
    //do something...
}

//assumes you've registered for drag events (e.g., in init):
//  [self registerForDraggedTypes:[NSArray arrayWithObject:NSFilenamesPboardType]];
- (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender {
    //cancel pending _mouseEntered: call:
    [NSObject cancelPreviousPerformRequestsWithTarget:self]; 
    NSLog(@"draggingEntered");
    NSPasteboard *pasteboard = [sender draggingPasteboard];
    return (([pasteboard.types containsObject:NSFilenamesPboardType]) ? NSDragOperationLink : NSDragOperationNone);
}

- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender {
    NSPasteboard *pasteboard = [sender draggingPasteboard];
    if ([pasteboard.types containsObject:NSFilenamesPboardType]) {
        for (NSString *filePath in [pasteboard propertyListForType:NSFilenamesPboardType]) {
            NSLog(@"dropped file: %@", filePath);
        }
    }
    return YES;
}