1


我有一个透明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
谢谢

4

1 回答 1

3

这是在您需要它以开始操作之后接收定义事件的经典情况。具体来说,直到拖动开始之后,您才能知道 mouseDown 是否是拖动的开始。但是,如果没有开始拖动,您希望对该 mouseDown 采取行动。

在 iOS 中(我意识到这与这里的代码没有直接关系,但它是指导性的),有一个完整的 API 围绕让 iOS 尝试为您做出这些决定而构建。整个手势系统是基于这样一种想法,即用户开始做某事可能是许多不同动作之一,因此需要随着时间的推移而解决,可能导致在跟踪期间取消动作。

在 OS X 上,我们没有很多系统可以帮助解决这个问题,所以如果你有一些需要不同地处理点击和拖动的东西,你需要推迟你的下一个动作,直到一个保护时间过去,如果通过,您可以执行原始操作。在这种情况下,您可能需要执行以下操作:

在 中mouseDown,开始一个NSTimer适当的保护时间(不要太长以至于人们会不小心移动指针,也不要太短以至于你会在用户拖动之前触发)以便稍后回调你以触发弹出框。

在 中mouseDragged,使用一个警戒区域来确保如果用户只是稍微抽搐,它不会算作拖拽。这可能很烦人,因为有时需要将某些东西拖得比开始拖动所需的距离要远,因此您需要在某个地方找到一个神奇的常数,或者进行一些实验。当超出警戒区域时,然后通过取消NSTimerwith开始您的合法拖动操作[timer invalidate]并进行拖动。

在计时器的回调中,显示您的弹出框。如果用户拖动,NSTimer则将无效,导致它不会触发,因此不会显示弹出框。

于 2012-06-05T02:24:14.940 回答