从NSButton动作中调用表情符号选择器与符号选择器

5

我是Swift的新手,目前正在为macOS开发一个小型消息应用程序。基本应用程序已经完成,但我想添加一个表情符号选择器。

我想添加一个按钮来打开“表情符号”窗口。这个窗口在启动应用程序时会自动添加到“编辑”菜单中,但我希望通过NSButton按下它弹出(就像本地的Mac Messages应用程序一样)。

是否有一种调用系统功能来显示表情符号选择器的方法,或者一种模拟键盘快捷方式(ctrl+cmd+space)的方法?如果有,我需要采取哪些步骤来实现它?


虽然我还没有找到触发表情符号的方法,但是看一下这个:https://dev59.com/VpXfa4cB1Zd3GeqPia24 - Ezekiel
肯定让我走上了正确的轨道。感谢您的帮助! - user6644425
3个回答

5

感谢使用键盘快捷方式的建议,我已经弄清楚了。

以下是我使用的代码。我在模拟两个修改键被按下时遇到了问题,因此解决方法是创建一个自定义的CGEventFlags项。

// Setup a custom CGEventFlags Item with value of .MaskControl and .MaskCommand
    let commandControlMask = (CGEventFlags.MaskCommand.rawValue | CGEventFlags.MaskControl.rawValue)
    let commandControlMaskFlags = CGEventFlags(rawValue: commandControlMask)!

    // Press Space key once
    let space = CGEventSourceCreate(.HIDSystemState)
    let keyDown = CGEventCreateKeyboardEvent(space, 49 as CGKeyCode, true)
    CGEventSetFlags(keyDown, commandControlMaskFlags)
    CGEventPost(.CGHIDEventTap, keyDown)
    let keyUp = CGEventCreateKeyboardEvent(space, 49 as CGKeyCode, false)
    CGEventSetFlags(keyUp, commandControlMaskFlags)
    CGEventPost(.CGHIDEventTap, keyUp)

请注意,在应用程序运行于沙盒环境时,发布这些事件是无效的。我不知道还有哪个API可以在应用程序沙盒的限制内完成此任务。 - chockenberry
11
原文:Turns out you can use [NSApp orderFrontCharacterPalette:nil] to accomplish this: http://twitter.com/lapcatsoftware/status/859539614373117952翻译:原来你可以使用[NSApp orderFrontCharacterPalette:nil]来完成这个操作:http://twitter.com/lapcatsoftware/status/859539614373117952。 - chockenberry
@chockenberry 你是如何将字符板中的字符返回到你的应用程序中的? - Clifton Labrum
...你如何强制让弹出窗口作为气泡出现在特定的NSTextField上?我已经将其设置为第一响应者,但字符面板仍然显示为浮动窗口。 - Clifton Labrum
1
@CliftonLabrum 返回字符是自动的。只需将您的textView作为发送方传递即可。所以[NSApp orderFontCharacterPalette:textView],但请确保在之前调用becomeFirstResponder方法来激活textView。 - Amerino

2

使用IBOutlets的简单示例

class ViewController: NSViewController {

    @IBOutlet weak var textView: NSTextField!

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
    }

    override var representedObject: Any? {
        didSet {
        // Update the view, if already loaded.
        }
    }

    @IBAction func buttonTapped(_ sender: Any) {
        textView.becomeFirstResponder()
        NSApp.orderFrontCharacterPalette(textView)
    }
}

你也可以直接传递 nil - NSApp.orderFrontCharacterPalette(nil)。只需确保你的 textView 是第一响应者即可。你可以轻松地桥接 orderFrontCharacterPalette 以在 Catalyst 应用程序中使用。 - Amerino

0
let commandControlMask = (CGEventFlags.maskCommand.rawValue | CGEventFlags.maskControl.rawValue)
let commandControlMaskFlags = CGEventFlags(rawValue: commandControlMask)

 // Press Space key once
let space = CGEventSource(stateID: .hidSystemState)
let keyDown = CGEvent(keyboardEventSource: space, virtualKey: 49 as CGKeyCode, keyDown: true)
keyDown?.flags = commandControlMaskFlags
keyDown!.post(tap: .cghidEventTap)
let keyUp = CGEvent(keyboardEventSource: space, virtualKey: 49 as CGKeyCode, keyDown: false)
keyUp?.flags = commandControlMaskFlags
keyUp?.post(tap: .cghidEventTap)

已更新至Swift 5.1。但需要用户授予辅助功能权限。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接