Use Binding<Int> with a TextField SwiftUI Use Binding<Int> with a TextField SwiftUI xcode xcode

Use Binding<Int> with a TextField SwiftUI


Actually , you can binding manyTypes with TextField:

      @State var weight: Int = 0      var body: some View {       Group{       Text("\(weight)")       TextField("Weight", value: $weight, formatter: NumberFormatter())    }}


Of course it is possible to use

TextField("", value: $value, formatter: NumberFormatter())//    .keyboardType(UIKeyboardType.decimalPad) // << uncomment for num pad

and even with Numeric Pad, but this does not prevent to enter non-numeric characters into such TextField, and until commit formatter is not called to validate input. Maybe Apple will give us possibility to validate input on the fly in future, but not now, ... so I prefer different way

Here is my approach to have text field for numeric values (Int, Float, Double, etc.) which validates input and limits of specific type (say do not allow to enter values longer then fit into Int maximum allowed value). Hope it would be helpful for someone as well. (Of course configurations like font, size, colors, etc. are possible per usage needs)

struct NumberTextField<V>: UIViewRepresentable where V: Numeric & LosslessStringConvertible {    @Binding var value: V    typealias UIViewType = UITextField    func makeUIView(context: UIViewRepresentableContext<NumberTextField>) -> UITextField {        let editField = UITextField()        editField.delegate = context.coordinator        return editField    }    func updateUIView(_ editField: UITextField, context: UIViewRepresentableContext<NumberTextField>) {        editField.text = String(value)    }    func makeCoordinator() -> NumberTextField.Coordinator {        Coordinator(value: $value)    }    class Coordinator: NSObject, UITextFieldDelegate {        var value: Binding<V>        init(value: Binding<V>) {            self.value = value        }        func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange,                       replacementString string: String) -> Bool {            let text = textField.text as NSString?            let newValue = text?.replacingCharacters(in: range, with: string)            if let number = V(newValue ?? "0") {                self.value.wrappedValue = number                return true            } else {                if nil == newValue || newValue!.isEmpty {                    self.value.wrappedValue = 0                }                return false            }        }        func textFieldDidEndEditing(_ textField: UITextField, reason: UITextField.DidEndEditingReason) {            if reason == .committed {                textField.resignFirstResponder()            }        }    }}struct TestTextFieldWithNumbers: View {    @State private var value = 0    var body: some View {        VStack {            Text("Current value: \(value)")            Divider()            TextField("", value: $value, formatter: NumberFormatter())//                .keyboardType(UIKeyboardType.decimalPad)            Divider()            NumberTextField(value: $value)                .frame(height: 32)        }    }}struct TestTextFieldWithNumbers_Previews: PreviewProvider {    static var previews: some View {        TestTextFieldWithNumbers()    }}


Just to make it more observable.

change this:

TextField("", text: $intvalue)

to that

TextField("Value", value: $amount, formatter: NumberFormatter())