Skip to content

Instantly share code, notes, and snippets.

@joniden
Created May 27, 2020 06:10
Show Gist options
  • Save joniden/65d3987d2e0289f3deb1e9a14d4f5d9c to your computer and use it in GitHub Desktop.
Save joniden/65d3987d2e0289f3deb1e9a14d4f5d9c to your computer and use it in GitHub Desktop.
OTP Pin code view, hidden text field and enter single digit in each text field
import SwiftUI
import Introspect
/**
Used like this:
PinStackView { pin, success in
self.passCodeFilled = success
}
*/
struct PinStackView: View {
var maxDigits = 6
@State var pin = ""
// String is the pin code, bool is completed or not
var handler: ((String, Bool) -> Void)
func getPinNumber(_ index: Int) -> String {
let pin = Array(self.pin)
if pin.indices.contains(index), !String(pin[index]).isEmpty {
return String(pin[index])
}
return "0"
}
var body: some View {
ZStack {
backgroundField
HStack {
ForEach(0..<maxDigits) { digit in
Text(self.getPinNumber(digit)).padding().background(Color(.systemFill))
}
}
}
}
private var backgroundField: some View {
let boundPin = Binding<String>(get: { self.pin }, set: { newValue in
self.pin = newValue
if newValue.count == self.maxDigits {
self.closeKeyboard()
}
self.handler(newValue, newValue.count == self.maxDigits)
})
return TextField("", text: boundPin).introspectTextField { textField in
textField.becomeFirstResponder()
textField.isHidden = true
}
.keyboardType(.numberPad)
}
private func closeKeyboard() {
UIApplication.shared.endEditing() // Closing keyboard does not exist for swiftui yet
}
}
struct PinStackView_Previews: PreviewProvider {
static var previews: some View {
PinStackView { pin, success in
print(pin)
}
}
}
extension UIApplication {
func endEditing() {
sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment