Emoji keyboard SwiftUi
Asked Answered
D

1

7

I want to make an emoji text box where it would be possible to write the only emoji and better so that the emoji keyboard appears. The emoji keyboard is standard. I am writing a program in SwiftUI. Found this code, does it work for me? If so, how do you use it? If not, which one do you need?

Thank!

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()
            }
        }
    }
Darciedarcy answered 27/2, 2021 at 10:29 Comment(0)
S
16

Use UIViewRepresentable for wrapped UITextField to SwiftUI

Here is a demo.

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")
    }
}

enter image description here



If you want to switch the keyboard from Normal to Emoji and vice versa. You can use the below code.

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)
        }
    }
}

enter image description here

Specie answered 27/2, 2021 at 10:42 Comment(12)
Wow! Thanks! But do you know how to prohibit the entry of any other symbols besides these and limit the number of 3?Gardell
@ИванПокасов you can use combine to limit your character like this EmojiTextField(text: $text, placeholder: "Enter emoji", isEmoji: $isEmoji) .onReceive(Just(text), perform: { _ in self.text = String(text.prefix(3)) })Specie
isEmoji? how to define it? Will this only allow three emojis and not allow other characters to be entered?Gardell
If you use the first way then no need for isEmoji and this is just to allow you to enter only 3 times. for the allow other char you need to override canPerformAction to disable past action like this https://mcmap.net/q/1477657/-how-to-make-text-typed-in-textfield-undeletableSpecie
Damn, I don't understand ... In fact, I need an input line of 3 emoji, but so that other letters, as shown by you, are not entered. Only emojis were allowed.Gardell
@ИванПокасов check this https://mcmap.net/q/1477658/-how-to-make-sure-that-only-emoji-can-be-entered-in-the-textfield-swiftuiSpecie
@ИванПокасов what you need 3 lines or only 3 emojis? If you have some reference please attach.Specie
I need a string. We will consider this as a user-supplied title. But only 3 emojis are allowed.Gardell
i figured out how your textbox works. Very good job, thank you. Is it possible to edit it? Increase the font size of the text field or its location, so that when you open it, it does not move far up?Gardell
do you have any suggestions?Gardell
You can set font inside the text field class and for the position it behaves like normal SwiftUI text field so you can search on google.Specie
Is it possible to make it so that when the text field is called emoji, the keyboard of the asama opens?Gardell

© 2022 - 2024 — McMap. All rights reserved.