在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()。 有没有解决方法呢?
提前致谢。
答案 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;
}