Skip to content

drewster99/swiftui-pin-pad

Repository files navigation

SwiftUI PIN Pad

Platform Swift License

SPM Version

A customizable PIN entry component for SwiftUI (iOS 18+, macOS 15+).

PIN Pad Demo

Installation

Add this package to your project via Swift Package Manager:

dependencies: [
    .package(url: "https://github.com/drewster99/swiftui-pin-pad.git", from: "1.0.0")
]

Demo Project

A demo project is available at swiftui-pin-pad-demo.

Usage

import swiftui_pin_pad

SwiftUIPINPad {
    Text("Enter PIN")
        .font(.title)
} onPINComplete: { pin in
    guard pin == "1234" else {
        return .indicateInvalidPIN  // Shakes and clears
    }
    // PIN is correct - handle authentication
    return .doNothing
}

With change callback

SwiftUIPINPad {
    Text("Enter PIN")
} onPINChange: { pin in
    // onPINChange is optional and is fired every time the user
    // adds a digit or deletes one
    
    print("Current PIN: \(pin)")
    return .doNothing
} onPINComplete: { pin in
    // Validate PIN
    if pin == "1234" {
        // Do whatever you need here to remove the
        // pin pad view and allow access
        return .doNothing // or .clearPIN, if you prefer
    } else {
        // wrong pin - shake and clear
        return .indicateInvalidPIN
    }
}

Customization

SwiftUIPINPad(requiredLength: 6) {
    Text("6-Digit PIN")
} onPINComplete: { pin in
    // Handle 6-digit PIN
    return .doNothing
}
.pinPadIncludesButtonLetters(false)  // Hide ABC/DEF letters
.pinPadButtonSpacing(30)             // Adjust button spacing

Cancel button

SwiftUIPINPad {
    Text("Enter PIN")
} onPINComplete: { pin in
    return pin == "1234" ? .doNothing : .indicateInvalidPIN
} onCancel: {
    // Handle cancel button press
}

// Or hide the cancel button
SwiftUIPINPad(showCancelButton: false) {
    Text("Enter PIN")
} onPINComplete: { pin in
    return .doNothing
}

External PIN state

@State private var currentPIN = ""

SwiftUIPINPad(pin: $currentPIN) {
    Text("Enter PIN")
} onPINComplete: { pin in
    return .doNothing
}

Features

  • Configurable PIN length (default: 4)
  • Optional cancel button with callback
  • External PIN state binding
  • Shake animation for invalid PIN
  • Optional letter labels on buttons
  • Customizable spacing
  • Keyboard shortcuts: digits, Delete, Escape
  • Glass button style on iOS 26+ / macOS 26+

Notes

  • Enforces minimum size of 350x700, looks for ideal size of 400x800, and max size of 500x825. This seems to work well for all phones and iPads that I've tested

License

MIT License

Copyright & Credits

Written by Andrew Benson Copyright (C) 2025 Nuclear Cyborg Corp

About

Numeric passcode / PIN entry for SwiftUI, configurable length. Includes shake animation to indicate wrong password and easy validation callback (your code just does the validation). Looks similar to iOS/iPadOS pin pad.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages