Meu objetivo: tenho um aplicativo macOS criado e quero...
- Tem um botão para abrir o seletor de emojis (consegui isso)
- Quando o usuário seleciona um emoji, intercepte esse valor com
NSResponder
- Em seguida, use-o na etiqueta do meu botão
O código abaixo é uma simplificação. Preciso de ajuda: Como posso interceptar o valor do NSResponder e imprimi-lo?
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)
}
}
Alguém pode me dar uma dica sobre como resolver isso? O que acontece agora: o seletor de emoji é aberto, mas nada acontece depois de selecionar um emoji
Observação: estou usando a solução desta discussão - https://stackoverflow.com/a/77797594/5133585 . Mas espero uma solução sem um TextField oculto.
A razão pela qual não quero usar um TextField aqui:
Eu tenho uma lista que percorre um array. Em cada linha, existem 3 TextFields: [emoji] —— [nome] —— [data]
Quando seleciono uma linha e pressiono Enter no macOS, ela se concentra no campo de texto emoji. O que eu quero é focar no nome TextField. Portanto, espero remover este emoji TextField e resolver esse problema.
O seletor de emoji deve se concentrar em algo e deve ser algo sobre o qual você tenha controle para obter o que está selecionado.
Se você não gosta de focar em um arquivo oculto
TextField
, pode focar no botão que abre o seletor de emojis. Crie umaNSButton
subclasse que esteja em conformidade comNSTextInputClient
, como nesta resposta , e envolva-a em um arquivoNSViewRepresentable
.Como você mencionou um selecionável
List
com linhas contendo campos de texto, aqui está um exemplo de uso em uma situação semelhante. Isso simplesmente imprime o emoji selecionado.Para que o seletor de emoji apareça como um pop-up, a visualização focada anteriormente antes de fazer isso
orderFrontCharacterPalette
deve ser um campo de texto. Então se você quiser que o pop-up apareça no botão, você ainda terá que colocar um invisÃvelNSTextView
no centro do botão.Talvez como este campo de texto esteja no lado do AppKit, o SwiftUI não saiba disso e não terá o comportamento de foco indesejável ao pressionar a tecla Enter.
Quando o botão for pressionado, defina o socorrista para a visualização de texto invisÃvel e, em seguida, chame de forma assÃncrona
orderFrontCharacterPalette
.Aqui está um exemplo de implementação.