article

Thursday, March 24, 2022

SwiftUI Highlight and Shake Invalid Username and Password with show password toggle

SwiftUI Highlight and Shake Invalid Username and Password with show password toggle

ContentView.swift
 
//
//  ContentView.swift
//  SwiftUIProject
//
//  Created by Cairocoders
//

import SwiftUI

struct ContentView: View {
    
    @State var username = ""
    @State var password = ""
    @State var invalidpassword = 0
    @State var invalidusername = 0
    @State private var showText: Bool = false
    
    var body: some View {
        VStack {
            HStack{
                Image("logo")
                    .resizable()
                    .frame(width: 150, height: 130, alignment: .center)
            }
            
            HStack {
                Image(systemName: "person")
                    .foregroundColor(.gray)
                TextField("Username", text: $username)
            }
            .padding()
            .background(Color("Color"))
            .cornerRadius(8)
            .overlay(RoundedRectangle(cornerRadius: 8)
                .stroke(lineWidth: 1)
                .foregroundColor(invalidusername == 0 ? Color.clear : Color.red)
            )
            .padding(.bottom, 20)
            .modifier(ShakeEffect(animatableData: CGFloat(invalidusername)))
            
            HStack {
                Image(systemName: "lock")
                    .foregroundColor(.gray)
                if showText {
                    TextField("", text: $password)
                }else {
                    SecureField("Password", text: $password)
                }
                Button(action: {
                    showText.toggle()
                }, label: {
                    Image(systemName: showText ? "eye.slash.fill" : "eye.fill")
                        .foregroundColor(.gray)
                })
            }
            .padding()
            .background(Color("Color"))
            .cornerRadius(8)
            .overlay(RoundedRectangle(cornerRadius: 8)
                .stroke(lineWidth: 1)
                .foregroundColor(invalidpassword == 0 ? Color.clear : Color.red)
            )
            .padding(.bottom, 20)
            .modifier(ShakeEffect(animatableData: CGFloat(invalidpassword)))
            
            Button(action: {
            
            }, label: {
                Text("Forgot password").padding()
            })
            
            Button(action: {
                withAnimation(.default) {
                    loginUser()
                }
            }, label: {
                Text("Login")
                    .font(.headline).bold().foregroundColor(.white).padding()
                    .frame(width: 250, height: 50)
                    .background(Color.blue)
                    .cornerRadius(10)
            })
            
            HStack {
                Text("Don't have an account?")
                
                Button(action: {
                    
                }, label: {
                    Text("Sign Up")
                })
            }.padding()
            
        }.padding()
    }
    
    private func loginUser() {
        if username == "" {
            self.invalidusername += 1
            print("Username is required")
        } else if password == "" {
            self.invalidpassword += 1
            self.invalidusername = 0
            print("password is required")
        }else {
            self.invalidpassword = 0
            print("email : \(username) pass : \(password)")
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

struct ShakeEffect : GeometryEffect {
    var travelDistance : CGFloat = 6
    var numOfShake : CGFloat = 4
    var animatableData: CGFloat
    
    func effectValue(size: CGSize) -> ProjectionTransform {
        ProjectionTransform(CGAffineTransform(translationX: travelDistance * sin(animatableData * .pi * numOfShake), y: 0))
    }
}

Related Post