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()
}
}