I've been trying to wrap a UITextField in UIViewRepresentable in order to do some customisation but this does not seem to work.
My main issue is that the frame of the UITextField is wrong. I even raised a TSI for this. It was confirmed to be a bug (I raised a bug report) but was told that the only work around is effectively to completely re-write my own Text Field using the basics. I cannot believe something as simple as this has not been solved yet.
Below is my minimum code to show the problem. I've tried a lot of things: adding InputView to a ScrollView; constraining the frame of InputView, etc. The problem is that when you keep on typing to fill the UITextField then it's frame gets a negative x-offset and it goes off the screen so that you can no longer see the cursor.
How do I fix this, or do I really have no choice but to re-write UITextField?
import SwiftUI
struct InputView: UIViewRepresentable {
let fontName = "Arial"
let fontSize: CGFloat = 32.0
@Binding var text: String
typealias UIViewType = UITextField
func makeUIView(context: Context) -> UIViewType {
// Setup text view:
// ----------------
let textView = UITextField()
textView.delegate = context.coordinator
// Creae a dummy view for the inputView (keyboard) so that the default
// keyboard is not shown:
let dummyView = UIView(frame: CGRect.zero)
textView.inputView = dummyView
return textView
}
func makeCoordinator() -> InputView.Coordinator {
return Coordinator(self)
}
func updateUIView(_ textView: UIViewType, context: Context) {
if textView.text != text {
textView.text = text
}
}
class Coordinator: NSObject, UITextFieldDelegate {
var parent: InputView
init(_ parent: InputView) {
self.parent = parent
}
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
if let currentValue = textField.text as NSString? {
let proposedValue = currentValue.replacingCharacters(in: range, with: string) as String
self.parent.text = proposedValue
}
return true
}
}
}
struct ContentView: View {
@State private var text: String = "Type here"
var body: some View {
VStack {
InputView(text: $text)
Text(text)
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}