gpt4 book ai didi

objective-c - NSWindow 移动期间的通知

转载 作者:搜寻专家 更新时间:2023-10-30 20:12:20 24 4
gpt4 key购买 nike

NSWindow 的位置通过拖动其标题栏而改变时,如何获得通知?我知道我可以使用 windowWillMove:windowDidMove: 通知,但它们只会在拖动开始或完成时给我一个通知。

最佳答案

我有一个解决方案,可以让您在拖动窗口时确定窗口的位置。

这两个问题是,当窗口被拖动时,没有内置的方法来获得通知,并且窗口的框架在停止移动之前不会更新。我的方法通过设置重复计时器并跟踪光标的位移来解决这些问题。

首先订阅NSWindowWillMoveNotificationNSWindowDidMoveNotification确定窗口何时开始和停止移动。

[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(windowWillMove:)
name:@"NSWindowWillMoveNotification"
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(windowDidMove:)
name:@"NSWindowDidMoveNotification"
object:nil];

当窗口即将移动时,记录光标的位置并启动一个重复计时器,调用您自己的“窗口正在被拖动”方法。

- (void)windowWillMove:(NSNotification *)notification {
if (notification.object == self.view.window) { // make sure we have the right window
self.dragCursorStartPos = [NSEvent mouseLocation];
const NSTimeInterval dragDelaySeconds = 0.1; // polling rate delay
self.dragWindowTimer = [NSTimer scheduledTimerWithTimeInterval:dragDelaySeconds
target:self
selector:@selector(myMethod)
userInfo:nil
repeats:YES];
}
}

当窗口完成移动时,停止重复计时器。

- (void)windowDidMove:(NSNotification *)notification {
if (notification.object == self.view.window) { // make sure we have the right window
if (self.dragWindowTimer != NULL) {
[self.dragWindowTimer invalidate];
self.dragWindowTimer = NULL;
}
}
}

现在,聪明/hacky 的部分是我们确定框架的实际位置,方法是计算光标相对于其起始位置的位移,并将此位移添加到框架报告的原点,该原点自此以来一直没有改变 window 开始移动。

- (void)myMethod {
NSPoint cursorPos = [NSEvent mouseLocation];
NSPoint cursorDisplacement = NSMakePoint(cursorPos.x - self.dragCursorStartPos.x, cursorPos.y - self.dragCursorStartPos.y);
CGPoint frameOrigin = self.view.window.frame.origin;
CGPoint actualFrameOrigin = CGPointMake(frameOrigin.x + cursorDisplacement.x, frameOrigin.y + cursorDisplacement.y);
NSLog(@"The frame's actual origin is (%f, %f)", actualFrameOrigin.x, actualFrameOrigin.y);
}

actualFrameOrigin指向 myMethod将报告框架的实际位置,即使 self.view.window.frame.origin点仅在您停止拖动窗口时更新。

这种方法可以让您在拖动窗口时收到通知,并告诉您它的实际位置,这样您就一切就绪了!


我发现的唯一问题是在不移动光标的情况下快速按下标题栏会触发 NSWindowWillMoveNotification但不是 NSWindowDidMoveNotification ,这会导致计时器错误地继续重复。为了处理这种情况,我们可以在 myMethod 中检查鼠标左键是否被按住。通过检查是否 (pressedButtons & (1 << 0)) == (1 << 0) .如果按钮没有被按住,我们就取消计时器。

关于objective-c - NSWindow 移动期间的通知,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5248132/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com