iOS 스터디가 있는데 매주 공부한 내용을 한번에 사용할 수 있는 화면을 구현해보고 있거든용
이번주 월요일은 로그인 화면을 구현하는 것을 목표로 잡고 스터디를 하기로 했어요.
왜냐? SwiftUI의, @State, @Binding, TextField에 대해서 공부했기 때문이죠.
구현조건
- 이메일 텍스트 필드는 이메일 키보드가 나오도록 설정
- 비밀번호 텍스트 필드는 암호화 되어서 보이도록 설정
- 이메일, 비밀번호 텍스트 필드에 값이 있고, 토글이 활성화 되어야 버튼도 활성화 되도록 설정
요 3가지가 일단 공통적으로 구현하자고 약속한 조건이었슴다.
그래서 먼저 아이디, 비밀번호 텍스트 필드부터 구현을 하고자 했으나..
UIKit과는 다르게 테두리가 없어서(?) style를 따로 설정해줘야 하더라구요.
근데 저는 안에 이미지도 넣고 싶어서 이미지랑 텍스트 필드를 HStack으로 묶고,
그 위에 테두리를 overlay해서 올려서 구현했어요. 그 부분이 바로 요 코드 부분
@State var login: String = ""
// ID 텍스트 필드
HStack {
Image(systemName: "person").frame(width: 20)
.font(.system(size: 25))
.foregroundColor(.gray)
TextField("E-mail", text: $login)
.frame(width: 300, height: 30)
.keyboardType(.emailAddress) //email 형식으로 입력 받도록
.textCase(.lowercase)
.autocapitalization(.none) // 대문자 설정 지우기
.disableAutocorrection(false) // 자동 수정 설정 해제
}
.padding()
.overlay(RoundedRectangle(cornerRadius: 4).stroke(Color.black, lineWidth: 2))
.padding(.bottom, 10)
그리고 비밀번호 텍스트 필드는 암호화 되어서 표현되도록 하는 것이라서
찾아보았더니 SecureField라는걸 활용하면 된다고 해서 필드 종류를 제외하고 아이디랑 똑같은 조건으로 구현해씀다!
@State var password: String = ""
HStack {
Image(systemName: "key").frame(width: 20)
.font(.system(size: 25))
.foregroundColor(.gray)
SecureField("Password", text: $password)
.frame(width: 300, height: 30)
.autocapitalization(.none)
}
.padding()
.overlay(RoundedRectangle(cornerRadius: 4).stroke(Color.black, lineWidth: 2))
기능에 대해서 잠깐 정리를 해보자면…
이메일 형식의 키보드로 만들기 위해서
- .keyboardType(.emailAddress) : 키보드 이메일 형식으로 만들기 ( 종류는 URL, NamePhonePad, NumberPad 등 다양함)
- .textCase(.lowercase) : 소문자만 입력되도록 하는것 (upper도 있음)
- .autocapitalization(.none) : 키보드 맨처음 칠 때, 대문자로 시작하는 설정 없애기!
- .disableAutocorrection(false) : 자동 수정 해제 설정하기
그리고 overlay는 뷰위에 하나의 뷰를 올려주는 형식이라고 생각하면 됨! (샌드위치 마냥..)
근데 하다보니까... UIKit에는 클리어 버튼이 있는데 스유는 없나? 하고 찾아봤더니
아니 자료가 너무 없는거에용... 'ㅅ' 하지만 찾고 찾다가 발견했습니다. (링크가 넘 길어서.. 밑에 넣어둘게요..)
보니까 .onAppear을 통해서 구현하면 되더라구요!
.onAppear란 모냐.. 디벨로퍼를 찾아보면, 뷰가 올라올 때 {} 안에 명시한 기능을 추가해 주는 것이라고 합니다.
그래서 이거를 스택 뒤에 추가해서 어떤걸 해줄건지를 추가해주면 돼요.
이렇게 쓰시면.. 텍스트 필드에 값을 입력할 때 clear Button이 생깁니당
.onAppear {
UITextField.appearance().clearButtonMode = .whileEditing
} // clear Button 구현
이제 조건을 위한 토글을 구현해볼게요. 제일 쉬이이우어용
@State var isLogin: Bool = false
Toggle("Agree to ierms and conditions", isOn: $isLogin)
.frame(width: 300, alignment: .trailing)
상태 값이기 때문에 맨처음 값을 false로 설정해서 상태프로퍼티를 만들고
Toggle에 그 값을 넣고 크기만 설정해주면 끝!
마지막은 버튼 만들기!
Button {
print("로그인 중입니다.")
} label: {
Text("Sign in")
.fontWeight(.bold)
.frame(width: 360, height: 50)
.background(.blue)
.foregroundColor(.white)
.cornerRadius(10)
}
.disabled(!isButtonValid())
.padding(.bottom, 200)
위에서 버튼 활성화에 조건을 걸어 놓았잖아요 ?!
그래서 .disabled로 조건을 걸어놓았습니다.
disabled가.. 활성/비활성의 조건? 걸어줄 수 있거든요....?
디벨로퍼에서 disabled를 찾아보면..
“사용자가 이 뷰와 상호 작용할 수 있는지 여부를 제어하는 조건을 추가합니다.” 라고 나와있어요.
그래서 버튼이 활성화 되는 조건을 함수로 설정하고 !함수 해서 함수에 반대되는 경우 비활성화 되도록 했어요!
아이디, 비밀번호의 TextField의 count가 > 1 이거나, 토글이 활성화 되어 있다면 true를 리턴하도록 했습니당
func isButtonValid() -> Bool {
return login.count > 1 && password.count > 1 && isLogin == true
}
그래서 최종적으로 어떻게 돌아가냐면..
근데 음 딱 맨처음 화면에 들어왔을때 키보드가 먼저 올라오게 반응하도록 만들고 싶고
아이디에서 return 치면 비밀번호 입력하는 텍스트 필드로 넘어가도록도 만들고 싶고
화면의 다른 부분을 눌렀을 때 텍스트 필드가 자동으로 내려가는 것도 구현하고 싶어요.
그리고 코드를 좀 깔끔하게^^.. 정리하고 싶네요.
(근데 브랜치 따서 쓰는거고.. 앞으로 계속 이렇게 하나씩 다 빼면 너무 프로젝트 폴더들이 지저분해질것 같아서 참고 이쒀요)
ㅋㅋㅋ
아직 많이 추가해보고 찾아볼게 많군요!
UIKit이랑 생각보다 많이 다르고 .. 다른것 같네요.
추가 또는 만들고 싶은 것들은 구현하는대로 다른 게시물로 정리해볼려구욤
그럼 오포끝!!
++) 최종 코드
import SwiftUI
struct LonginSY: View {
@State var login: String = ""
@State var password: String = ""
@State var isLogin: Bool = false
func isButtonValid() -> Bool {
return login.count > 1 && password.count > 1 && isLogin == true
}
var body: some View {
VStack {
Text("Log in")
.font(.system(size: 70))
.fontWeight(.medium)
.frame(width: 350, alignment: .leading)
.padding(.bottom, 10)
Spacer()
// 중간 문장
Text("Introduce your credentials")
.frame(width: 350, alignment: .leading)
// ID 텍스트 필드
HStack {
Image(systemName: "person").frame(width: 20)
.font(.system(size: 25))
.foregroundColor(.gray)
TextField("E-mail", text: $login)
.frame(width: 300, height: 30)
.keyboardType(.emailAddress) //email 형식으로 입력 받도록
// .textCase(.lowercase)
.autocapitalization(.none) // 대문자 설정 지우기
.disableAutocorrection(false) // 자동 수정 설정 해제
}
.padding()
.overlay(RoundedRectangle(cornerRadius: 4).stroke(Color.black, lineWidth: 2))
.padding(.bottom, 10)
// Password 텍스트 필드
HStack {
Image(systemName: "key").frame(width: 20)
.font(.system(size: 25))
.foregroundColor(.gray)
SecureField("Password", text: $password)
.frame(width: 300, height: 30)
.autocapitalization(.none)
}
.padding()
.overlay(RoundedRectangle(cornerRadius: 4).stroke(Color.black, lineWidth: 2))
// 토글
Toggle("Agree to ierms and conditions", isOn: $isLogin)
.frame(width: 300, alignment: .trailing) // 정렬 적용 안 되는듯..
// 버튼
.padding(.bottom, 50)
Button {
print("로그인 중입니다.")
print(isButtonValid())
} label: {
Text("Sign in")
.fontWeight(.bold)
.frame(width: 360, height: 50)
.background(.blue)
.foregroundColor(.white)
.cornerRadius(10)
}
.disabled(!isButtonValid())
.padding(.bottom, 200)
}
.onAppear {
UITextField.appearance().clearButtonMode = .whileEditing
} // clear Button 구현
}
}
++) 참고한 블로그
SwiftUI TextField Clear button - 텍스트 필드 내용 지우기, 초기화
SwiftUI에서 TextField의 내용을 초기화하거나 입력중인 내용을 다 지우고 싶을수도 있다. 그리고 입력필드에 전체 내용을 지울 수 있는 버튼을 생성해놓으라는 내용은 애플의 HIG에도 명시가 되어
archanwriteup.tistory.com
'모공모공 스터디' 카테고리의 다른 글
[SwiftUI] TextField, Button, Toggle을 사용하여 SwiftUI로 간단한 로그인 화면 업그레이드 구현 (0) | 2023.07.24 |
---|---|
[SwiftUI] List를 활용해서 채팅방 목록 화면 구현하기 (0) | 2023.07.17 |
[UIKit] TextField, Button, Toggle을 사용하여 UIKit으로 간단한 로그인 화면 구현하기 (0) | 2023.07.04 |