Reputation: 95
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()
}
}
}
Upvotes: 9
Views: 8018
Reputation: 18914
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")
}
}
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)
}
}
}
Upvotes: 19