我的目标:我已经构建了一个 macOS 应用程序,并且我想要...
- 有一个按钮可以打开表情符号选择器(管理这个)
- 当用户选择一个表情符号时,使用以下代码截取该值
NSResponder
- 然后在我的按钮标签上使用它
下面的代码是简化的。我需要帮助:如何从 NSResponder 截取值并打印它?
import SwiftUI
import AppKit
struct ContentView: View {
private let emojiResponder = EmojiResponder()
var body: some View {
Button {
// open the emoji picker
if let window = NSApplication.shared.keyWindow {
window.makeFirstResponder(emojiResponder)
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
NSApp.orderFrontCharacterPalette(nil)
}
}
} label: {
Text("Emoji?")
}
.onAppear {
emojiResponder.onEmojiSelected = { selectedEmoji in
print(selectedEmoji)
}
}
}
}
// Custom Emoji NSResponder
class EmojiResponder: NSResponder {
var onEmojiSelected: ((String) -> Void)?
// use insertTest method from NSResponder
// I assume this allows me to get the input
override func insertText(_ insertString: Any) {
guard let selectedEmoji = insertString as? String else { return }
onEmojiSelected?(selectedEmoji)
print(selectedEmoji)
}
}
有人能指点我如何解决这个问题吗?现在发生了什么:表情符号选择器已打开,但我选择表情符号后什么也没发生
注意:我正在使用此讨论中的解决方案 - https://stackoverflow.com/a/77797594/5133585。 但我希望有一个没有隐藏 TextField 的解决方案。
我不想在这里使用 TextField 的原因是:
我有一个循环遍历数组的列表。每行有 3 个 TextField:[表情符号] —— [姓名] —— [日期]
当我在 macOS 上选择一行并按下 Enter 键时,它会聚焦在表情符号文本字段上。我想要的是聚焦在名称文本字段上。因此,我希望删除这个表情符号文本字段并解决这个问题。
表情符号选择器必须关注某些东西,并且它必须是你可以控制的东西,才能得到所选择的内容。
如果您不喜欢将焦点放在隐藏的 上
TextField
,则可以将焦点放在打开表情符号选择器的按钮上。创建一个NSButton
符合 的子类NSTextInputClient
,就像在这个答案中一样,并将其包装在 中NSViewRepresentable
。由于您提到了
List
包含文本字段的行的可选项,下面是类似情况下的示例用法。这只是打印出所选的表情符号。要让表情符号选择器以弹出窗口的形式显示,之前聚焦的视图
orderFrontCharacterPalette
必须是文本字段。因此,如果您希望弹出窗口显示在按钮上,您仍然需要NSTextView
在按钮的中心放置一个不可见的元素。也许由于这个文本字段在 AppKit 端,SwiftUI 不知道它,并且在按下返回键时不会出现不良的焦点行为。
当按钮被按下时,将第一响应者设置为不可见的文本视图,然后异步调用
orderFrontCharacterPalette
。这是一个示例实现。