Text insertion in UIViewRepresentable-wrapped UITextField goes haywire after inserting emoji

Folks, I'm trying to understand what I'm missing here. In a SwiftUI project, I've wrapped a UITextView in UIViewRepresentable as a replacement for SwiftUI's TextEditor control, largely so that I can get it to become/resign first responder status.

This minimally-viable example works fine, except for one bug that I can't seem to resolve: if I add an emoji anywhere in that text view, then text insertion goes haywire — wherever I have the cursor, the character typed will be inserted, but then the cursor immediately jumps to the end of the text in the field.

Code Block swift
import SwiftUI
struct WrappedTextView: UIViewRepresentable {
class Coordinator: NSObject, UITextViewDelegate {
@Binding var text: String
var didBecomeFirstResponder: Bool = false
init(text: Binding<String>) {
_text = text
}
func textViewDidChangeSelection(_ textView: UITextView) {
DispatchQueue.main.async {
self.text = textView.text ?? ""
}
}
}
@Binding var text: String
var isFirstResponder: Bool = false
func makeUIView(context: UIViewRepresentableContext<WrappedTextView>) -> UITextView {
let textView = UITextView()
textView.delegate = context.coordinator
return textView
}
func makeCoordinator() -> WrappedTextView.Coordinator {
return Coordinator(text: $text)
}
func updateUIView(_ uiView: UIViewType, context: UIViewRepresentableContext<WrappedTextView>) {
uiView.text = text
if isFirstResponder && !context.coordinator.didBecomeFirstResponder {
uiView.becomeFirstResponder()
context.coordinator.didBecomeFirstResponder = true
}
}
}


Credit to this Stack Overflow answer for the above code: https://stackoverflow.com/a/56508132

Can someone help me understand what I'm doing wrong?

There's an example project available here, wrapping both UITextField and UITextView in UIViewRepresentable: https://github.com/AngeloStavrow/WrappedTextInputExample
Answered by Angelo in 646342022
Okay, this bug can be resolved if you make the following change to the updateUIView(_: context:) function:

Code Block swift
func updateUIView(_ uiView: UIViewType, context: UIViewRepresentableContext<WrappedTextView>) {
if (uiView.text != text) {
uiView.text = text
}
if isFirstResponder && !context.coordinator.didBecomeFirstResponder {
uiView.becomeFirstResponder()
context.coordinator.didBecomeFirstResponder = true
}
}

Accepted Answer
Okay, this bug can be resolved if you make the following change to the updateUIView(_: context:) function:

Code Block swift
func updateUIView(_ uiView: UIViewType, context: UIViewRepresentableContext<WrappedTextView>) {
if (uiView.text != text) {
uiView.text = text
}
if isFirstResponder && !context.coordinator.didBecomeFirstResponder {
uiView.becomeFirstResponder()
context.coordinator.didBecomeFirstResponder = true
}
}

Text insertion in UIViewRepresentable-wrapped UITextField goes haywire after inserting emoji
 
 
Q