SwiftUI中实现仅支持Emoji输入的文本框:给定EmojiTextField代码适用性及使用方案咨询
嘿,我来帮你搞定这个Emoji文本框需求!
一、先说说你找到的这段代码
这段EmojiTextField子类能满足自动唤起并锁定Emoji键盘的核心需求,但有个小缺陷:它只管控了键盘的唤起和锁定,没限制输入内容——比如用户如果粘贴了非Emoji字符,文本框还是会接收。所以要完全实现“仅允许输入Emoji”的目标,得给它补充内容过滤的逻辑。
二、怎么在SwiftUI里用这个TextField?
SwiftUI没法直接使用UIKit的UITextField子类,得用UIViewRepresentable把它包装成SwiftUI能识别的组件,具体步骤如下:
1. 编写包装组件的代码
struct EmojiTextFieldView: UIViewRepresentable { @Binding var text: String var placeholder: String func makeUIView(context: Context) -> EmojiTextField { let textField = EmojiTextField() textField.placeholder = placeholder textField.delegate = context.coordinator // 这里可以自定义样式,比如字体大小、对齐方式 textField.font = UIFont.systemFont(ofSize: 24) textField.textAlignment = .center return textField } func updateUIView(_ uiView: EmojiTextField, context: Context) { uiView.text = text } func makeCoordinator() -> Coordinator { Coordinator(parent: self) } // 用Coordinator处理输入内容过滤 class Coordinator: NSObject, UITextFieldDelegate { let parent: EmojiTextFieldView init(parent: EmojiTextFieldView) { self.parent = parent } // 拦截输入,只保留Emoji字符 func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { // 计算输入后的完整文本 let newText = (textField.text as NSString?)?.replacingCharacters(in: range, with: string) ?? string // 过滤出仅包含Emoji的内容 let emojiOnlyText = newText.filter { $0.isEmoji } // 更新绑定的文本值 parent.text = emojiOnlyText // 返回false,因为我们已经手动处理了文本更新 return false } } } // 给Character扩展一个判断是否为Emoji的方法 extension Character { var isEmoji: Bool { let scalarValue = String(self).unicodeScalars.first!.value // 覆盖常见的Emoji Unicode范围 switch scalarValue { case 0x1F600...0x1F64F, 0x1F300...0x1F5FF, 0x1F680...0x1F6FF, 0x1F1E0...0x1F1FF, 0x2600...0x26FF, 0x2700...0x27BF, 0xFE00...0xFE0F, 0x1F900...0x1F9FF, 0x1F004...0x1F0CF: return true default: return false } } }
2. 在你的SwiftUI视图中使用该组件
struct ContentView: View { @State private var emojiText = "" var body: some View { VStack(spacing: 20) { EmojiTextFieldView(text: $emojiText, placeholder: "来输入Emoji呀~") .padding() .border(Color.gray) Text("你输入的Emoji:\(emojiText)") .font(.title) } .padding() } }
三、有没有更原生的SwiftUI方案?
如果你不想折腾UIKit子类,也可以用SwiftUI原生的TextField实现,代码更简洁:
struct EmojiOnlyTextField: View { @Binding var text: String var placeholder: String var body: some View { TextField(placeholder, text: $text) .keyboardType(.emoji) // 唤起Emoji键盘 .onChange(of: text) { newValue in // 实时过滤,只保留Emoji text = newValue.filter { $0.isEmoji } } .padding() .border(Color.gray) } }
不过这个方案有个小缺点:用户可以手动切换到其他键盘(比如英文键盘),而之前的UITextField子类方案会强制锁定Emoji键盘,用户无法切换。如果你的需求是必须只能使用Emoji键盘,那还是优先选择第一种方案哦~
内容的提问来源于stack exchange,提问作者Иван Покасов
相关产品推荐
相关产品推荐

