我有一个透明NSWindow
,其中有一个简单的图标,可以在屏幕上拖动
我的代码是:
.H:
@interface CustomView : NSWindow{
}
@property (assign) NSPoint initialLocation;
的.m
@synthesize initialLocation;
- (id) initWithContentRect: (NSRect) contentRect
styleMask: (NSUInteger) aStyle
backing: (NSBackingStoreType) bufferingType
defer: (BOOL) flag{
if (![super initWithContentRect: contentRect
styleMask: NSBorderlessWindowMask
backing: bufferingType
defer: flag]) return nil;
[self setBackgroundColor: [NSColor clearColor]];
[self setOpaque:NO];
[NSApp activateIgnoringOtherApps:YES];
return self;
}
- (void)mouseDragged:(NSEvent *)theEvent {
NSRect screenVisibleFrame = [[NSScreen mainScreen] visibleFrame];
NSRect windowFrame = [self frame];
NSPoint newOrigin = windowFrame.origin;
// Get the mouse location in window coordinates.
NSPoint currentLocation = [theEvent locationInWindow];
// Update the origin with the difference between the new mouse location and the old mouse location.
newOrigin.x += (currentLocation.x - initialLocation.x);
newOrigin.y += (currentLocation.y - initialLocation.y);
// Don't let window get dragged up under the menu bar
if ((newOrigin.y + windowFrame.size.height) > (screenVisibleFrame.origin.y + screenVisibleFrame.size.height)) {
newOrigin.y = screenVisibleFrame.origin.y + (screenVisibleFrame.size.height - windowFrame.size.height);
}
// Move the window to the new location
[self setFrameOrigin:newOrigin];
}
- (void)mouseDown:(NSEvent *)theEvent {
// Get the mouse location in window coordinates.
self.initialLocation = [theEvent locationInWindow];
}
我想在用户点击透明窗口的图片时显示NSPopover
。但是,正如您在代码中看到的那样,mouseDown
事件用于获取鼠标位置(上面的代码来自一个示例)。
如果用户点击图标只是拖动图标或只是点击图标以显示NSPopover
,我该怎么办?
谢谢
答案 0 :(得分:2)
这是在您需要它之后接收定义事件以开始操作的经典情况。具体来说,在拖动开始之前,您无法知道mouseDown是否是拖动的开始。但是,如果拖动没有开始,您希望对该mouseDown采取行动。
在iOS中(我意识到这与代码没有直接关系,但它是指导性的),有一个完整的API围绕让iOS尝试为您做出这些决定。整个Gesture系统基于这样的想法:用户开始做一些可能是许多不同操作之一的事情,因此需要随着时间的推移解决,可能导致在跟踪期间取消操作。
在OS X上,我们没有很多系统可以帮助解决这个问题,所以如果你需要处理点击和差异拖动的东西,你需要推迟你的下一个动作,直到保护时间过去,如果通过,您可以执行原始操作。在这种情况下,您可能希望执行以下操作:
在mouseDown
中,开始NSTimer
设置适当的保护时间(不会太久以至于人们会不小心移动指针,而不是那么短,以至于在用户拖动之前你会触发)为了稍后再回电话来触发弹出窗口。
在mouseDragged
中,使用保护区域以确保如果用户稍微抽搐一下,则不会将其视为拖拽。这可能会令人恼火,因为它有时会导致为了开始拖动而需要拖动比看起来更远的东西,因此您需要在某处找到魔法常量,或者进行一些实验。超过警戒区域后,通过使用NSTimer
取消[timer invalidate]
并开始拖动来开始合法的拖动操作。
在计时器的回调中,显示你的弹出窗口。如果拖动用户,NSTimer
将失效,导致它不会触发,因此弹出窗口不会显示。