Giter Site home page Giter Site logo

swiftui-numberfield's Introduction

NumberField: Real-time NumberFormatter Validation of TextField Input

One of the most frustrating parts of building SwiftUI-based apps at the moment is dealing with input validation of numeric values. As of this writing, the native support for numberFormatters in TextFields appears to be broken.

Various folks[1] have suggested that the way around this is to create a Binding<String> that manages conversion between string and numeric values. This is indeed possible -- and is part of what this code does. But there is currently an additional problem with TextField, and IIRC, it's also a maddening problem with UITextField in UIKit: Input validation (and the associated conversion of string to numeric values) happens either too often or not often enough.

In a naive version of the use-a-binding approach, string to numeric and back to string conversion occurs with each keystroke, which is a nightmare if you are using a currency format. The string "1" gets converted to 1.0 which gets converted to "$1.00" with the insertion point not between the dollar sign and the numeral one. Comma and decimal point handling is similarly frustrating for the user.

If you try to deal with this problem by implementing string validation and conversion only when focus is lost, you are now in a position where your numeric state object does not reflect the most recent value entered by the user. This makes it impossible to type "12.34" and then tap a button that then consumes the converted decimal. More subtley, you will not be able to guard the button's enabled state using something like Button("Add"){ ... }.disabled(myNumber==nil).

One way of partially mitigating some of these issues is using onCommit: but its behavaior if not broken is at least awkward. Most importantly, your onCommit: closure (only) fires when the user taps return on a text field, which means 1) more stale value problems and 2) using the decimal pad keyboard means your onCommit: handler will never be fired.

I finally figured out an approach that works well for my needs, and it is based on the insight that things get much simpler if an additional numeric value is introduced. One Decimal holds the most recent numeric value as of the last loss of focus, which reflects the formatted appearance of the field when the user is not interacting with it. The other Decimal holds the most recent converted value as of the last keystroke. The insight is that you want to convert on a per-keystroke basis but you do not want to use that conversion to update the text field string contents until after the user is no longer typing in the field.

Please enjoy. Pull requests et c. welcome.

[1]: See this Stack Overflow post and this Twitter thread.

swiftui-numberfield's People

Contributors

edw avatar upetersen avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.