How to build a Password Strength Meter in SwiftUI

Artem Mykhelson
3 min readFeb 7, 2025

--

In today’s digital age, ensuring strong passwords is essential for safeguarding user data. A visual strength meter not only guides users towards creating robust passwords but also enhances the user experience. In this tutorial, we’ll walk through creating a simple yet effective password strength meter using SwiftUI.

What We’ll Build

We’ll create a password strength meter that evaluates the strength of a password based on certain criteria (length, inclusion of numbers, uppercase letters, and special characters). The strength will be displayed both textually and visually using a colored bar.

Step 1: Setting Up the Project

Start by creating a new SwiftUI project in Xcode. Once set up, we’ll dive into building our password strength view.

Step 2: Defining the Password Strength Enum

We need an enumeration to represent the different levels of password strength. Each level will have an associated color to visually represent the strength.

enum PasswordStrength: String {
case weak = "Weak"
case medium = "Medium"
case strong = "Strong"

var color: Color {
switch self {
case .weak:
return .red
case .medium:
return .orange
case .strong:
return .green
}
}
}

Here, we have three cases: weak, medium, and strong, each with a corresponding color.

Step 3: Creating the Strength Bar

Next, we’ll build a visual component, StrengthBar, that changes its appearance based on the password strength.

struct StrengthBar: View {
var strength: PasswordStrength

var body: some View {
GeometryReader { geometry in
switch strength {
case .weak:
HStack {
StrenghtBarSegment(color: strength.color, maxWidth: geometry.size.width/3)
ForEach(0..<2) { _ in
StrenghtBarSegment(color: .secondary, maxWidth: geometry.size.width/3)
}
}.frame(maxHeight: 8)
case .medium:
HStack {
ForEach(0..<2) { _ in
StrenghtBarSegment(color: strength.color, maxWidth: geometry.size.width/3)
}
StrenghtBarSegment(color: .secondary, maxWidth: geometry.size.width/3)
}.frame(maxHeight: 8)
case .strong:
HStack {
ForEach(0..<3) { _ in
StrenghtBarSegment(color: strength.color, maxWidth: geometry.size.width/3)
}
}.frame(maxHeight: 8)
}
}.frame(maxHeight: 8)
}
}

struct StrenghtBarSegment: View {
var color: Color
var maxWidth: CGFloat

var body: some View {
RoundedRectangle(cornerRadius: 4)
.fill(color)
.frame(height: 8)
.frame(maxWidth: maxWidth)
}
}

This component uses a GeometryReader to ensure the bars adjust to the available width. Depending on the password strength, it fills different portions of the bar.

Step 4: Building the Password Strength View

Now, let’s bring everything together in the main PasswordStrengthView.

struct PasswordStrengthView: View {
@Binding var password: String
@State private var strength: PasswordStrength = .weak
var body: some View {
HStack {
StrengthBar(strength: strength)
Text(strength.rawValue)
.foregroundColor(strength.color)
.font(.system(size: 16, weight: .semibold))
}
.animation(.easeInOut, value: strength)
.onAppear {
strength = evaluatePasswordStrength(password)
}
.onChange(of: password) { _, newValue in
strength = evaluatePasswordStrength(newValue)
}
}

func evaluatePasswordStrength(_ password: String) -> PasswordStrength {
if password.isEmpty {
return .weak
}

let lengthCriteria = password.count >= 8
let numberCriteria = password.rangeOfCharacter(from: .decimalDigits) != nil
let uppercaseCriteria = password.rangeOfCharacter(from: .uppercaseLetters) != nil
let specialCharacterCriteria = password.rangeOfCharacter(from: CharacterSet.punctuationCharacters) != nil

let score = [lengthCriteria, numberCriteria, uppercaseCriteria, specialCharacterCriteria].filter { $0 }.count

switch score {
case 0...1:
return .weak
case 2...3:
return .medium
default:
return .strong
}
}
}

Explanation:

  • Binding Password: The @Binding var password: String allows this view to react to changes in the password from a parent view.
  • Password Evaluation: The evaluatePasswordStrength function checks four criteria:
  1. Password length (at least 8 characters)
  2. Inclusion of numbers
  3. Presence of uppercase letters
  4. Special characters

Based on these checks, it assigns a strength level.

  • Animation & Updates: The onChange modifier updates the strength as the user types.

Step 5: Previewing the Component

To see the strength meter in action, let’s add a preview.

struct PasswordStrengthView_Previews: PreviewProvider {
static var previews: some View {
PasswordStrengthView(password: .constant("Password123!"))
.padding()
.previewLayout(.sizeThatFits)
}
}

This preview provides a quick look at how the meter responds to a strong password.

Conclusion

You’ve now built a functional password strength meter using SwiftUI! This component can be easily integrated into any sign-up or password reset form to guide users in creating secure passwords.

Feel free to expand upon this by adding more complex criteria, such as checking for dictionary words or implementing a more nuanced scoring system. Happy coding!

Enjoying this content? Support me!

Creating quality content takes time and effort, and your support helps keep it going! If you found this article helpful, consider buying me a coffee — it’s a small gesture that makes a big difference.

👉 Buy Me a Coffee

Thanks for your support! 💛

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

--

--

Artem Mykhelson
Artem Mykhelson

Written by Artem Mykhelson

🚀 Code | 🎮 Game | 🎨 Create | 📝 Tech Reviews 💻 Sharing the process – Join the journey! 🔥

No responses yet

Write a response