拖动事件未接收如果mouseEntered()事件由Cocoa App跟踪

时间:2018-02-05 07:38:49

标签: objective-c macos cocoa nsview nsevent

在Cocoa应用程序上工作,应用程序需要做两件事 - :

1)鼠标进入或退出

2)将鼠标拖到应用程序

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

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

- (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叫

     

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

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

提前致谢。

1 个答案:

答案 0 :(得分:0)

我可能错了,但我相信拖动操作取决于鼠标进入视图,所以如果你跟踪鼠标事件,将始终首先调用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;
}