You have seen the iOS lock screen, every time your phone misses to recognize your face or fingerprint. Do you want to implement the same for your app?
Let’s get started!
We are going to implement the above screen today. It can be used for entering a passcode, pin, OTP and many more.
Once you learn how this is implemented you can change the circles with squares, dashes or asterisks to suit your requirement. I implemented this primarily for OTP and circles seem the best fit for me.
Let me share the full code and explain the pieces in it, one by one.
The core idea is that a text field and the circle images are added to a
ZStack at the same position, with
textField above the images in Z axis and the elements in the
textField are set
The images equal to the number of
maxDigits, which defaults to four, are inside a
HStack . Based on the number of characters the user has entered, we show a circle border or a filled circle. Tapping the
showPin button which looks like an eye, will show the numbers which the user has entered.
There is no
delegate to get changes as the user types in the
textField. Hence, we are using this workaround of a
Binding<String>. Even this entire
PasscodeField is a workaround. If Apple provides a proper way to conform to
TextFieldStyle protocol, none of this might be required.
ToggleStyle protocols are super cool and make life much easier.
Let us get back to the code now. Every time the value changes, we call a method and check if the user has entered maximum digits. If yes, we disable the
textField and call the completion handler block.
If you can notice, contrary to many implementations of
SwiftUI out in the web, I implemented this using
UITextField is required only for making it the first responder on appearing as mentioned in the comments of the gist, so other things should work across all
SwiftUI supported platforms.
By the way, the Introspect library I’ve used for making it the first responder is useful in other cases also. You can check it out.