的CGEventTapCreate()
的callback
參數是一個C函數指針, 和在夫特1.x中這是不可能用夫特函數參數調用它。
然而,在夫特2(Xcode的7),其採取函數指針參數,C功能 可以使用閉包或全局函數(條件是 閉合不能捕獲任何其本地上下文的限制)被調用。
作爲一個例子,這裏是 Receiving, Filtering, and Modifying Key Presses and Releases 斯威夫特一個完整的翻譯:
import Foundation
func myCGEventCallback(proxy : CGEventTapProxy, type : CGEventType, event : CGEvent, refcon : UnsafeMutablePointer<Void>) -> Unmanaged<CGEvent>? {
if [.KeyDown , .KeyUp].contains(type) {
var keyCode = CGEventGetIntegerValueField(event, .KeyboardEventKeycode)
if keyCode == 0 {
keyCode = 6
} else if keyCode == 6 {
keyCode = 0
}
CGEventSetIntegerValueField(event, .KeyboardEventKeycode, keyCode)
}
return Unmanaged.passRetained(event)
}
let eventMask = (1 << CGEventType.KeyDown.rawValue) | (1 << CGEventType.KeyUp.rawValue)
guard let eventTap = CGEventTapCreate(.CGSessionEventTap,
.HeadInsertEventTap,
.Default,
CGEventMask(eventMask),
myCGEventCallback,
nil) else {
print("failed to create event tap")
exit(1)
}
let runLoopSource = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, eventTap, 0)
CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, kCFRunLoopCommonModes)
CGEventTapEnable(eventTap, true)
CFRunLoopRun()
更新斯威夫特3:
import Foundation
func myCGEventCallback(proxy: CGEventTapProxy, type: CGEventType, event: CGEvent, refcon: UnsafeMutableRawPointer?) -> Unmanaged<CGEvent>? {
if [.keyDown , .keyUp].contains(type) {
var keyCode = event.getIntegerValueField(.keyboardEventKeycode)
if keyCode == 0 {
keyCode = 6
} else if keyCode == 6 {
keyCode = 0
}
event.setIntegerValueField(.keyboardEventKeycode, value: keyCode)
}
return Unmanaged.passRetained(event)
}
let eventMask = (1 << CGEventType.keyDown.rawValue) | (1 << CGEventType.keyUp.rawValue)
guard let eventTap = CGEvent.tapCreate(tap: .cgSessionEventTap,
place: .headInsertEventTap,
options: .defaultTap,
eventsOfInterest: CGEventMask(eventMask),
callback: myCGEventCallback,
userInfo: nil) else {
print("failed to create event tap")
exit(1)
}
let runLoopSource = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, eventTap, 0)
CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, .commonModes)
CGEvent.tapEnable(tap: eventTap, enable: true)
CFRunLoopRun()
感謝您的答覆。有沒有與@objc_blocks的任何經驗來解決這種情況? – chrisp
@jacobsd:CGEventTapCreate()將C函數指針作爲參數,而不是Objective-C塊。我不認爲你可以用Swift 1.2(Xcode 6.4)回調來解決這個問題。 –
Holy Heck,比C/Objective-C版本更醜陋...感嘆...至少它是*可能的* – uchuugaka