Project/TeamStudy

SwiftUI를 이용해서 LoginView 만들기

oreoOz 2023. 6. 26. 01:04

스터디 조원들끼리 뭘 만들까 하다가 로그인 화면을 만들어보기로 함.

스유랑 유킷 둘 다 각각 만들어 볼꺼임!

 

다음 조건들을 포함하고 있어야 한다.

  • 아이디 칸에는 이메일 형식만 입력될 수 있도록 한다.
  • 아이디, 비밀번호 두개의 칸 모두가 입력되고, 토글 버튼이 켜져 있어야 회원가입 버튼이 활성화되도록 한다.
  • 비밀번호 필드는 암호화되어 있어야 한다.

아래 이미지가 만들고자 한 화면의 예시임.

로그인 뷰 예시

우선 다음과 같이 프로퍼티를 만들었봤습니당

뷰 안에서 값이 변경되므로 바인딩을 위해 @State를 붙혀주었구여

    @State var id: String = ""
    @State var password: String = ""
    
    
    @State var isToggle: Bool = false
    @State private var showingAlert = false
    @State var signMessage: String = "default"

 

TextField 안에 "id", "input password"와 같이 플레이스홀더 값을 주었구요

text 매개변수에 $ 를 붙여 바인딩하여 값에 변화가 생긴다면 뷰에 적용될 수 있도록 할 수 있습니다!

패스워드를 입력하는 필드는 SecureField라는 필드를 가져와서 썼어요.

이러면 입력값이 안보임 ㅋㅋ

                        TextField("id", text: $id)
                            .padding()
                            .background(Color(uiColor: .secondarySystemBackground))
                            .cornerRadius(8)

                        SecureField("input password", text: $password)
                            .padding()
                        //.border(Color.gray)
                            .background(Color(uiColor: .secondarySystemBackground))
                            .cornerRadius(8)

 

그 다음은 이제 Sign in 버튼을 만들어 줬습니다.

버튼의 액션 부분은 

showingAlert.toggle()을 이용해서 showingAlert 값을 토글시킬 수 있습니다.

그래서 값이 true가 된다면 Alert를 동작시킬 수 있도록 해서 알림을 주도록 했습니당

값이 입력되지 않으면 버튼이 동작하지 않도록 disabled안에 다음과 같이 || 로 조건을 넣어줬습니당

            Button {
                // 알람을 뜨게하기 위해성
                showingAlert.toggle()
                signIn(id: id)
                // 버튼이 동작안할 때 색을 어둡게하고싶은데 어케하징
                if isToggle {
                    
                }
            } label: {
                Text("Sign in")
                    .padding()
            }
            .disabled(!isToggle || id.isEmpty || password.isEmpty)
            .frame(width: 360)
            .background(Color.blue)
            .foregroundColor(Color.white)
            .cornerRadius(10)
            //근데 색을 설정해놔서 disabled가 되도 티가 안남 ㅋㅋ;;
            .alert(isPresented: $showingAlert) {
                Alert(title: Text(""), message: Text(signMessage),
                      dismissButton: .default(Text("닫기")))
            }

아이디에 이메일 형식으로 입력되는지 확인하기 위해서는 정규표현식과 NSPredicate을 이용했어요

사실 정규표현식은... 인터넷에서 긁어와서... 정확하게는 잘 모르는데요..

문자열 입력에 표현식을 이용해서 제약을 줄 수 있다.. 정도?

정규 표현식에 대해서는 제대로 공부한 뒤에 한번 글로 작성해보게씁니다!

    func checkId(_ id: String) -> Bool {
        let emailRegex = "^[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,6}+$"
        let emailPredicate = NSPredicate(format: "SELF MATCHES %@", emailRegex)
        let isValid = emailPredicate.evaluate(with: id)
        return isValid
    }

 

 

 

 

 

전체 코드는 다음과 같습니다

import SwiftUI

struct ContentView: View {
    @State var id: String = ""
    @State var password: String = ""
    
    
    @State var isToggle: Bool = false
    @State private var showingAlert = false
    @State var signMessage: String = "default"
    
    var body: some View {
        VStack {
            Text("Log in")
                .fontWeight(.bold)
                .padding(.trailing, 250)
                .padding(.bottom)
                .font(.largeTitle)
            
            VStack{
                Section(header: Text("Introduce your credentials")
                    .padding(.trailing, 150)){
    
                        TextField("id", text: $id)
                            .padding()
                            .background(Color(uiColor: .secondarySystemBackground))
                            .cornerRadius(8)

                        SecureField("input password", text: $password)
                            .padding()
                        //.border(Color.gray)
                            .background(Color(uiColor: .secondarySystemBackground))
                            .cornerRadius(8)
                    }
            }
            
            Toggle(isOn: $isToggle) {
                Text("Agree to terms and conditions")
            }
            .padding(.bottom, 30)
            
            Button {
                // 알람을 뜨게하기 위해성
                showingAlert.toggle()
                signIn(id: id)
                // 버튼이 동작안할 때 색을 어둡게하고싶은데 어케하징
                if isToggle {
                    
                }
            } label: {
                Text("Sign in")
                    .padding()
            }
            .disabled(!isToggle || id.isEmpty || password.isEmpty)
            .frame(width: 360)
            .background(Color.blue)
            .foregroundColor(Color.white)
            .cornerRadius(10)
            //근데 색을 설정해놔서 disabled가 되도 티가 안남 ㅋㅋ;;
            .alert(isPresented: $showingAlert) {
                Alert(title: Text(""), message: Text(signMessage),
                      dismissButton: .default(Text("닫기")))
            }
            Spacer()
            
        }
        .padding()
    }
    
    // NSPredicate 사용방법 공식문서 확인 후 정리
    func checkId(_ id: String) -> Bool {
        let emailRegex = "^[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,6}+$"
        let emailPredicate = NSPredicate(format: "SELF MATCHES %@", emailRegex)
        let isValid = emailPredicate.evaluate(with: id)
        return isValid
    }
    
    func signIn (id: String) {
        print(checkId(id))
        if checkId(id) {
            signMessage = "로그인 성공"
            print("sign -> \(signMessage)")
        } else if id.isEmpty || password.isEmpty {
            signMessage = "id 또는 pw가 입력되지 않음"
            self.id = ""
            password = ""
        } else {
            signMessage = "올바른 형식이 아님"
            self.id = ""
            password = ""
        }
        print("sign -> \(signMessage)")
    }
}

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