I would like to create a custom text field with some input buttons, on click of those buttons text field should update the value accordingly.
I have multiple options to set value in InputView
, so that if I edited InputView
and if I click on any button, the button should update the value.
here is my code
@main
struct AmountApp: App {
var body: some Scene {
WindowGroup {
InputView()
}
}
}
struct InputView: View {
@State var value: Double = 0.00
var body: some View {
VStack {
Text("Amount")
TextInput(value: $value).padding(.horizontal)
HStack(alignment: .center, spacing: 16) {
Button { value = 20 } label: { Text("20") }
Button { value = 30 } label: { Text("30") }
Button { value = 40 } label: { Text("40") }
}
Button { print(value) } label: {
Text("Print")
.padding(8)
.foregroundColor(.red)
}
}
}
}
struct TextInput: UIViewRepresentable {
@Binding var value: Double
func makeCoordinator() -> Coordinator { Coordinator(self) }
func updateUIView(_ uiView: UITextField, context: Context) { }
func makeUIView(context: Context) -> UITextField {
let textfield = UITextField()
textfield.placeholder = "Enter amount"
textfield.text = "\(value)"
textfield.keyboardType = .decimalPad
textfield.setContentHuggingPriority(.defaultHigh, for: .vertical)
textfield.setContentHuggingPriority(.defaultLow, for: .horizontal)
textfield.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
return textfield
}
class Coordinator: NSObject, UITextFieldDelegate {
var parent: TextInput
init(_ textField: TextInput) { self.parent = textField }
}
}
Help would be greatly appreciated, ~Good day.!!
CodePudding user response:
The binding value will not update if you don't implement theUITextFieldDelegate
method(s) to receive user input (SwiftUI Custom TextField with UIViewRepresentable Issue with ObservableObject and pushed View)
When you change the value from the SwiftUI side, your UIViewRepresentable needs to handle the change in updateUIView (pass the new value to UITextField)
Also remember to set textfield.delegate = context.coordinator
so that you receive events.
struct TextInput: UIViewRepresentable {
@Binding var value: Double
func makeCoordinator() -> Coordinator { Coordinator(self) }
// for handling swiftui-side modification to the binding (your buttons)
func updateUIView(_ uiView: UITextField, context: Context) {
uiView.text = value
}
func makeUIView(context: Context) -> UITextField {
let textfield = UITextField()
textfield.placeholder = "Enter amount"
textfield.text = "\(value)"
textfield.keyboardType = .decimalPad
textfield.setContentHuggingPriority(.defaultHigh, for: .vertical)
textfield.setContentHuggingPriority(.defaultLow, for: .horizontal)
textfield.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
textfield.delegate = context.coordinator // set the delegate
return textfield
}
class Coordinator: NSObject, UITextFieldDelegate {
var parent: TextInput
init(_ textField: TextInput) { self.parent = textField }
func textFieldDidEndEditing(_ textField: UITextField) {
if let text = textField.text {
parent.value = Double(text) ?? 0
} else {
parent.value = 0
}
}
}
}