【问题标题】:Emoji keyboard SwiftUi表情符号键盘 SwiftUi
【发布时间】:2021-05-29 13:02:11
【问题描述】:

我想制作一个表情符号文本框,可以在其中编写唯一的表情符号并且更好,以便出现表情符号键盘。表情符号键盘是标准的。我正在用 SwiftUI 编写程序。找到这个代码,它对我有用吗?如果是这样,你如何使用它?如果没有,你需要哪一个?

谢谢!

class EmojiTextField: UITextField {

       // required for iOS 13
       override var textInputContextIdentifier: String? { "" } // return non-nil to show the Emoji keyboard ¯\_(ツ)_/¯ 

        override var textInputMode: UITextInputMode? {
            for mode in UITextInputMode.activeInputModes {
                if mode.primaryLanguage == "emoji" {
                    return mode
                }
            }
            return nil
        }

    override init(frame: CGRect) {
            super.init(frame: frame)

            commonInit()
        }

        required init?(coder: NSCoder) {
            super.init(coder: coder)

             commonInit()
        }

        func commonInit() {
            NotificationCenter.default.addObserver(self,
                                                   selector: #selector(inputModeDidChange),
                                                   name: UITextInputMode.currentInputModeDidChangeNotification,
                                                   object: nil)
        }

        @objc func inputModeDidChange(_ notification: Notification) {
            guard isFirstResponder else {
                return
            }

            DispatchQueue.main.async { [weak self] in
                self?.reloadInputViews()
            }
        }
    }

【问题讨论】:

    标签: swift emoji


    【解决方案1】:

    使用UIViewRepresentable 将 UITextField 包装到 SwiftUI

    这是一个演示。

    class UIEmojiTextField: UITextField {
    
        override func awakeFromNib() {
            super.awakeFromNib()
        }
        
        func setEmoji() {
            _ = self.textInputMode
        }
        
        override var textInputContextIdentifier: String? {
               return ""
        }
        
        override var textInputMode: UITextInputMode? {
            for mode in UITextInputMode.activeInputModes {
                if mode.primaryLanguage == "emoji" {
                    self.keyboardType = .default // do not remove this
                    return mode
                }
            }
            return nil
        }
    }
    
    struct EmojiTextField: UIViewRepresentable {
        @Binding var text: String
        var placeholder: String = ""
        
        func makeUIView(context: Context) -> UIEmojiTextField {
            let emojiTextField = UIEmojiTextField()
            emojiTextField.placeholder = placeholder
            emojiTextField.text = text
            emojiTextField.delegate = context.coordinator
            return emojiTextField
        }
        
        func updateUIView(_ uiView: UIEmojiTextField, context: Context) {
            uiView.text = text
        }
        
        func makeCoordinator() -> Coordinator {
            Coordinator(parent: self)
        }
        
        class Coordinator: NSObject, UITextFieldDelegate {
            var parent: EmojiTextField
            
            init(parent: EmojiTextField) {
                self.parent = parent
            }
            
            func textFieldDidChangeSelection(_ textField: UITextField) {
                DispatchQueue.main.async { [weak self] in
                    self?.parent.text = textField.text ?? ""
                }
            }
        }
    }
    
    struct EmojiContentView: View {
        
        @State private var text: String = ""
        
        var body: some View {
            EmojiTextField(text: $text, placeholder: "Enter emoji")
        }
    }
    



    如果您想将键盘从普通切换到表情符号,反之亦然。您可以使用以下代码。

    class UIEmojiTextField: UITextField {
        
        var isEmoji = false {
            didSet {
                setEmoji()
            }
        }
        
        override func awakeFromNib() {
            super.awakeFromNib()
        }
        
        private func setEmoji() {
            self.reloadInputViews()
        }
        
        override var textInputContextIdentifier: String? {
            return ""
        }
        
        override var textInputMode: UITextInputMode? {
            for mode in UITextInputMode.activeInputModes {
                if mode.primaryLanguage == "emoji" && self.isEmoji{
                    self.keyboardType = .default
                    return mode
                    
                } else if !self.isEmoji {
                    return mode
                }
            }
            return nil
        }
        
    }
    
    struct EmojiTextField: UIViewRepresentable {
        @Binding var text: String
        var placeholder: String = ""
        @Binding var isEmoji: Bool
        
        func makeUIView(context: Context) -> UIEmojiTextField {
            let emojiTextField = UIEmojiTextField()
            emojiTextField.placeholder = placeholder
            emojiTextField.text = text
            emojiTextField.delegate = context.coordinator
            emojiTextField.isEmoji = self.isEmoji
            return emojiTextField
        }
        
        func updateUIView(_ uiView: UIEmojiTextField, context: Context) {
            uiView.text = text
            uiView.isEmoji = isEmoji
        }
        
        func makeCoordinator() -> Coordinator {
            Coordinator(parent: self)
        }
        
        class Coordinator: NSObject, UITextFieldDelegate {
            var parent: EmojiTextField
            
            init(parent: EmojiTextField) {
                self.parent = parent
            }
            
            func textFieldDidChangeSelection(_ textField: UITextField) {
                parent.text = textField.text ?? ""
            }
        }
    }
    
    struct EmojiContentView: View {
        
        @State private var text: String = ""
        @State private var isEmoji: Bool = false
        
        var body: some View {
            
            HStack{
                EmojiTextField(text: $text, placeholder: "Enter emoji", isEmoji: $isEmoji)
                Button("EMOJI") {
                    isEmoji.toggle()
                }.background(Color.yellow)
            }
        }
    }
    

    【讨论】:

    • 哇!谢谢!但是你知道如何禁止除这些之外的任何其他符号的输入并限制3的数量吗?
    • @ИванПокасов 你可以像这样使用 combine 来限制你的角色 EmojiTextField(text: $text, placeholder: "Enter emoji", isEmoji: $isEmoji) .onReceive(Just(text), perform: { _ in self.text = String(text.prefix(3)) })
    • 是表情符号吗?如何定义它?这会只允许三个表情符号而不允许输入其他字符吗?
    • 如果您使用第一种方式,则不需要isEmoji,这只是为了让您只输入3次。对于允许其他字符,您需要覆盖 canPerformAction 以禁用过去的操作,例如 stackoverflow.com/a/65840157/14733292
    • 妈的,我没看懂……其实我需要输入一行3个emoji,但是这样你显示的其他字母就不输入了。只允许使用表情符号。
    猜你喜欢
    • 1970-01-01
    • 2011-10-13
    • 1970-01-01
    • 2016-06-08
    • 1970-01-01
    • 1970-01-01
    • 2018-03-25
    • 2014-09-29
    • 2012-12-09
    相关资源
    最近更新 更多