Contents

drewster99/swiftui-pin-pad

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

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

Package Metadata

Repository: drewster99/swiftui-pin-pad

Default branch: main

README: README.md