You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SwiftUI中如何确保文本输入框仅能输入Emoji?及相关代码的应用疑问

在SwiftUI中实现仅允许输入Emoji的文本输入框

嘿,我来帮你把这段代码用在SwiftUI里,其实很简单,分几步走就行~

首先,你找到的这段代码是一个自定义UITextField子类,它的核心作用是强制系统显示Emoji键盘,但它还缺了关键的一步——阻止用户粘贴或输入非Emoji内容,我先把完整的优化版本给你:

class EmojiTextField: UITextField { 
    // 用于iOS 13及以上版本,确保键盘上下文正确识别
    override var textInputContextIdentifier: String? { "" } 

    // 强制返回Emoji输入模式,让键盘默认显示Emoji面板
    override var textInputMode: UITextInputMode? { 
        for mode in UITextInputMode.activeInputModes { 
            if mode.primaryLanguage == "emoji" { 
                return mode 
            } 
        } 
        return nil 
    }

    // 过滤非Emoji内容,确保输入的只有Emoji
    override func shouldChangeCharacters(in range: NSRange, replacementString string: String) -> Bool {
        // 检查输入的字符串是否全是Emoji(包含扩展表情符号)
        let isEmoji = string.unicodeScalars.allSatisfy { scalar in
            scalar.properties.isEmoji || scalar.properties.isExtendedPictographic
        }
        // 如果是删除操作(string为空)或者输入的是Emoji,就允许修改
        return string.isEmpty || isEmoji
    }
}

接下来,因为SwiftUI原生的TextField是基于UIKit的,我们需要用UIViewRepresentable把这个自定义的UITextField包装成SwiftUI能直接使用的View:

步骤1:创建SwiftUI包装器

写一个遵循UIViewRepresentable的结构体,完成桥接工作:

struct EmojiInputView: UIViewRepresentable {
    // 和SwiftUI的@State/@Binding配合,实现双向数据绑定
    @Binding var text: String
    // 输入框的占位符文本
    var placeholder: String

    // 创建并配置自定义的EmojiTextField
    func makeUIView(context: Context) -> EmojiTextField {
        let textField = EmojiTextField()
        textField.placeholder = placeholder
        textField.delegate = context.coordinator
        // 监听文本变化,同步到SwiftUI的绑定变量中
        textField.addTarget(context.coordinator, action: #selector(Coordinator.textChanged(_:)), for: .editingChanged)
        return textField
    }

    // 当SwiftUI状态变化时,更新UIKit控件的内容
    func updateUIView(_ uiView: EmojiTextField, context: Context) {
        if uiView.text != text {
            uiView.text = text
        }
    }

    // 创建Coordinator,处理TextField的代理和回调逻辑
    func makeCoordinator() -> Coordinator {
        Coordinator(self)
    }

    class Coordinator: NSObject, UITextFieldDelegate {
        var parent: EmojiInputView

        init(_ parent: EmojiInputView) {
            self.parent = parent
        }

        // 把UIKit TextField的文本同步到SwiftUI的绑定变量
        @objc func textChanged(_ textField: UITextField) {
            parent.text = textField.text ?? ""
        }
    }
}

步骤2:在SwiftUI视图中使用

现在你就可以像用普通TextField一样,在你的SwiftUI视图里调用这个自定义输入框了:

struct ContentView: View {
    // 用@State管理输入的Emoji文本
    @State private var emojiText = ""

    var body: some View {
        VStack(spacing: 20) {
            Text("请输入Emoji:")
                .font(.headline)
            
            // 使用我们的自定义Emoji输入框
            EmojiInputView(text: $emojiText, placeholder: "点击输入Emoji")
                .padding()
                .border(Color.gray.opacity(0.5))
                .cornerRadius(8)
            
            // 实时显示输入的Emoji
            Text("你输入的:\(emojiText)")
                .font(.largeTitle)
        }
        .padding()
    }
}

关键点说明

  • 优化后的EmojiTextField不仅强制打开Emoji键盘,还通过shouldChangeCharacters方法过滤了所有非Emoji内容,彻底杜绝了文字输入或粘贴的可能。
  • UIViewRepresentable的Coordinator负责处理UIKit和SwiftUI之间的数据同步,保证双向绑定正常工作。

内容的提问来源于stack exchange,提问作者Alexsey

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 09:22:45