기본 UI 구현하기 #8
CustomTextField & AuthHeaderView & RegistrationView
CustomTextField
Source
VStack(spacing: 40) {
TextField("Email", text: $email)
SecureField("Password", text: $password)
}
.padding(.horizontal, 32)
.padding(.top, 44)
LoginView에서 사용했던 두 개의 TextField는
이미지와 TextField 혹은 SecureField, Divider의 조합으로 이루어져 있다.
같은 UI가 동일하게 RegistrationView에서도 사용되기 때문에 재사용을 용이하게 하기 위해 모듈화 한다.
Source
struct CustomTextField: View {
let imageName: String
let placeholderText: String
let fieldType: FieldType
@Binding var text: String
enum FieldType {
case normal
case secure
}
var body: some View {
VStack {
HStack {
Image(systemName: imageName)
.resizable()
.scaledToFit()
.frame(width: 20, height: 20)
.foregroundColor(Color(.darkGray))
if fieldType == .secure {
SecureField(placeholderText, text: $text)
} else {
TextField(placeholderText, text: $text)
}
}
Divider()
.background(Color(.darkGray))
}
}
}
해당 CustomView는 systemName에 해당하는 imageName,
placeholder에 해당하는 placeholderText,
TextField의 타입에 해당하는 fieldType 세 개의 파라미터를 갖는다.
fieldType에 따라 SecureField 혹은 TextField를 사용해 UI를 구성한다.
파라미터로 직접 systemName을 받기 때문에 id나 pw 외의 값을 입력받는 데에도 사용할 수 있다는 것이 장점이다.
AuthHeaderView
LoginView와 RegistrationView는 상단의 문구만 다르지 동일한 UI를 가지고 있다.
이 부분도 재사용하기 위해 별도로 분리하면 유지보수에 조금 더 유리할 수 있다.
Source
struct AuthHeaderView: View {
let upperTitle: String
let lowerTitle: String
var body: some View {
VStack(alignment: .leading) {
HStack {
Spacer()
}
Group {
Text(upperTitle)
Text(lowerTitle)
}
.font(.largeTitle)
.fontWeight(.semibold)
}
.frame(height: 260)
.padding(.leading)
.background(Color(.systemBlue))
.foregroundColor(.white)
.clipShape(RoundedShape(corners: .bottomRight))
}
}
해당 CustomView는 upperTitle과 lowerTitle 두 개의 파라미터로 설정할 문자열을 받아
정해진 디자인대로 배치한다.
RegistrationView
RegistrationView는 LoginView와 거의 동일한 UI를 가지고,
앞서 많은 부분을 재사용할 수 있도록 모듈화 해 놓았기에 배치만 조금 수정해 주면 된다.
Source
struct RegistrationView: View {
@Environment(\.dismiss) var dismiss
@State private var email = ""
@State private var password = ""
@State private var userName = ""
@State private var fullName = ""
var body: some View {
VStack {
AuthHeaderView(upperTitle: "Get started.", lowerTitle: "Create your account")
VStack(spacing: 40) {
CustomTextField(imageName: "envelope", placeholderText: "Email", fieldType: .normal, text: $email)
CustomTextField(imageName: "person", placeholderText: "UserName", fieldType: .normal, text: $userName)
CustomTextField(imageName: "person", placeholderText: "FullName", fieldType: .normal, text: $fullName)
CustomTextField(imageName: "lock", placeholderText: "Password", fieldType: .normal, text: $password)
}
.padding(32)
Button {
print("signup function")
} label: {
Text("Sign Up")
.font(.headline)
.foregroundColor(.white)
.frame(width: 340, height: 50)
.background(Color(.systemBlue))
.clipShape(Capsule())
.padding()
}
.shadow(color: .gray.opacity(0.5), radius: 10)
Spacer()
Button {
dismiss()
} label: {
HStack {
Text("Already have an account?")
Text("Sign In")
.fontWeight(.semibold)
}
.foregroundColor(Color(.systemBlue))
.font(.footnote)
}
.padding(32)
}
.ignoresSafeArea()
.toolbar(.hidden)
}
}
동작은 다음과 같이 된다.
각자의 View에 서로 NavigationLink 혹은 dismiss가 동작하므로 자연스럽게 전환된다.
'프로젝트 > Twitter Clone App (w∕Firebase)' 카테고리의 다른 글
10. 기능 구현하기 #2 (0) | 2022.12.20 |
---|---|
09. 기능 구현하기 #1 (0) | 2022.12.13 |
07. 기본 UI 구성하기 #7 (0) | 2022.12.02 |
06. 기본 UI 구성하기 #6 (0) | 2022.12.01 |
05. 기본 UI 구성하기 #5 (0) | 2022.11.30 |