如何通過拖動標題欄來更改NSWindow
的位置? 我知道我可以使用windowWillMove:
和windowDidMove:
通知,但這些通知只會在拖動開始或結束時纔會發出通知。NSWindow移動中的通知
回答
我絕對沒有可可專家,但AFAIK windowDidMove
即使在你拖動並稍微休息時也會發出通知(鼠標左鍵仍然按下,鼠標不會移動半秒左右)。
怎麼樣看兩件事:你知道窗口拖動開始,你知道它什麼時候結束。觀察鼠標移動之間的時間,然後獲得移動的窗口位置。
的回答者說,一個可以使用的windowWillMove
事件開始,有一個計時器調用updateWindow
(這似乎是這裏的關鍵的東西),然後你可以定期讀取應該更新的幀屬性,然後在windowDidMove
處停止計時器。
我有一個解決方案,可以讓您確定拖動窗口的位置。
這兩個問題是,拖動窗口時沒有內置的方式獲得通知,並且窗口的框架在其停止移動之前不會更新。我的方法是通過設置重複計時器並跟蹤光標位移來解決這些問題。
首先,訂閱NSWindowWillMoveNotification
和NSWindowDidMoveNotification
以確定窗口何時開始和停止移動。
[[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;
}
}
}
現在,聰明/哈克的部分是,我們從它的起始位置計算光標的移動,添加這種位移框架的報告的起源,其中由於並沒有改變決定幀的實際位置窗戶開始移動。
- (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);
}
在myMethod
的actualFrameOrigin
點會報告,其中框架實際上是,即使self.view.window.frame.origin
點只有當你停止拖動窗口的更新。
這種方法可以讓你在窗口被拖動時得到通知,並告訴你它的實際位置,所以你都準備好了!
我發現的唯一的問題是,快速按下標題欄不移動光標將火NSWindowWillMoveNotification
但不NSWindowDidMoveNotification
,這將導致計時器錯誤地不斷重複。爲了處理這種情況,我們可以通過檢查(pressedButtons & (1 << 0)) == (1 << 0)
來檢查在myMethod
中是否按住鼠標左鍵。如果按鈕沒有按下,我們只需取消定時器。
- 1. 移動到移動通知解析
- 2. 移動網絡中的推送通知
- 3. NSWindow關閉時如何得到通知
- 4. 混合移動應用在移動應用中顯示通知
- 5. 如何移動NSWindow而不移動兒童NSWindows
- 6. 的Widevine DRM:AWS SNS移動推送通知
- 7. NSWindow的動畫setContent
- 8. Azure移動服務吐司通知
- 9. Ionic2推送通知頁面移動
- 10. 移動Web瀏覽器聲音通知
- 11. 鈦移動本地通知崩潰
- 12. Flex移動報警 - 本地通知
- 13. 是否有像「willShowWindow」這樣的NSWindow通知/委託方法?
- 14. Modal NSWindow再次變爲可見後的通知
- 15. iOS設備的通知中心移除通知
- 16. iPhone - 從通知中心移除的推送通知
- 17. 無法拖動或移動自定義NSWindow
- 18. 移動到無移動通信塔的移動通信?
- 19. 在移動設備上填充「通知」區域的Azure通知集線器
- 20. 動態更改NSWindow的contentViewController
- 21. 使用UI自動化獲取控件移動的通知
- 22. 通知活動的通知方法
- 23. 避免將另一NSWindow開放的NSWindow的自動釋放?
- 24. 如何知道NSWindow是否是前窗?
- 25. NSWindow中的底欄
- 26. HTML5通知無法在移動Chrome中使用
- 27. Azure通知中心:安排移動應用程序API
- 28. Windows Azure移動和通知中心服務
- 29. cordova azure移動應用和通知中心服務
- 30. 移動無邊界NSWindow完全覆蓋Web視圖
你有進一步的瞭解嗎?我還想知道窗口框架在拖動... – Georg 2014-04-10 11:41:21
@Georg,請參閱下面的答案。 :) – VinceFior 2015-07-12 05:33:15