[SwiftUI] TwitterClone: Authentication UI

Junyoung Parkยท2022๋…„ 11์›” 16์ผ
0

SwiftUI

๋ชฉ๋ก ๋ณด๊ธฐ
103/136
post-thumbnail
post-custom-banner

๐Ÿ”ด Let's Build Twitter with SwiftUI (iOS 15, Xcode 13, Firebase, SwiftUI 3.0)

TwitterClone: Authentication UI

๊ตฌํ˜„ ๋ชฉํ‘œ

  • ๋กœ๊ทธ์ธ UI ๊ตฌํ˜„

๊ตฌํ˜„ ํƒœ์Šคํฌ

  • ๋ฒ„ํŠผ ์ปดํฌ๋„ŒํŠธ
  • ํ…์ŠคํŠธ ํ•„๋“œ ์ปดํฌ๋„ŒํŠธ
  • ๋„ค๋น„๊ฒŒ์ด์…˜ ์—ฐ๊ฒฐ

ํ•ต์‹ฌ ์ฝ”๋“œ

func path(in rect: CGRect) -> Path {
        let path = UIBezierPath(roundedRect: rect, byRoundingCorners: corners, cornerRadii: CGSize(width: 80, height: 80))
        return Path(path.cgPath)
    }
  • ํŠน์ • ๋ชจ์„œ๋ฆฌ์˜ ๋‘ฅ๊ทผ ์ •๋„๋ฅผ ์ปค์Šคํ…€ํ•˜๋Š” ๋„ํ˜• ๋ทฐ

์†Œ์Šค ์ฝ”๋“œ

import SwiftUI

struct LoginView: View {
    @State private var email = ""
    @State private var password = ""
    var body: some View {
        // parent container
        VStack {
            
            // header view
            AuthenticationHeaderView(title: "Hello.\nWelcome Back")
            
            VStack(spacing: 40) {
                CustomInputField(imageName: "envelope", placeholderText: "Email", text: $email)
                CustomInputField(imageName: "lock", placeholderText: "Password", text: $password)
            }
            .padding(.horizontal, 32)
            .padding(.top, 44)
            
            HStack {
                Spacer()
                
                NavigationLink {
                    Text("Reset password view...")
                } label: {
                    Text("Forgot Password")
                        .font(.caption)
                        .fontWeight(.bold)
                        .foregroundColor(Color(.systemBlue))
                        .padding(.top)
                        .padding(.trailing, 24)
                }
            }
            Button {
                print("Sign In Here...")
            } label: {
                Text("Sign In")
                    .font(.headline)
                    .foregroundColor(.white)
                    .frame(width: 340, height: 50)
                    .background(Color(.systemBlue))
                    .clipShape(Capsule())
                    .padding()
            }
            .shadow(color: .gray.opacity(0.5), radius: 10, x: 0, y: 0)
            
            Spacer()
            
            NavigationLink {
                RegistrationView().navigationBarHidden(true)
            } label: {
                HStack {
                    Text("Don't have an account?")
                        .font(.footnote)
                    Text("Sign Up")
                        .font(.footnote)
                        .fontWeight(.semibold)
                }
            }
            .padding(.bottom, 32)
            .foregroundColor(Color(.systemBlue))
        }
        .ignoresSafeArea()
        .navigationBarHidden(true)
    }
}
  • ํ—ค๋” ๋ทฐ ๋ฐ ์ด๋ฉ”์ผ๊ณผ ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅ๋ฐ›์„ ์ˆ˜ ์žˆ๋Š” ์ปค์Šคํ…€ ํ…์ŠคํŠธ ํ•„๋“œ UI
  • ๋กœ๊ทธ์ธ ๊ด€๋ จ ๋„ค๋น„๊ฒŒ์ด์…˜ ๊ธฐ๋Šฅ: ์ƒˆ๋กœ์šด ๋น„๋ฐ€๋ฒˆํ˜ธ ๋ฆฌ์…‹ ๋˜๋Š” ํšŒ์›๊ฐ€์ž… ๋ฐ”์ธ๋”ฉ
  • ๋ฒ„ํŠผ ์ปดํฌ๋„ŒํŠธ ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅ
import SwiftUI

struct RegistrationView: View {
    @State private var email: String = ""
    @State private var userName: String = ""
    @State private var fullName: String = ""
    @State private var password: String = ""
    @Environment(\.presentationMode) var mode
    var body: some View {
        VStack {
            AuthenticationHeaderView(title: "Get Started.\nCreate your account")
            VStack(spacing: 40) {
                CustomInputField(imageName: "envelope", placeholderText: "Email", text: $email)
                CustomInputField(imageName: "person", placeholderText: "UserName", text: $userName)
                CustomInputField(imageName: "person", placeholderText: "Full Name", text: $fullName)
                CustomInputField(imageName: "lock", placeholderText: "Password", text: $password)
            }
            .padding(32)
            
            Button {
                print("Sign Up Here...")
            } 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, x: 0, y: 0)
            
            Spacer()
            
            Button {
                mode.wrappedValue.dismiss()
            } label: {
                HStack {
                    Text("Already have an account?")
                        .font(.footnote)
                    Text("Sign In")
                        .font(.footnote)
                        .fontWeight(.semibold)
                }
            }
            .padding(.bottom, 32)

        }
        .ignoresSafeArea()
    }
}
  • ๋กœ๊ทธ์ธ ๋ทฐ์™€ ๋™์ผํ•œ ์ปดํฌ๋„ŒํŠธ ๋ทฐ(ํ—ค๋”, ๋ฒ„ํŠผ, ํ…์ŠคํŠธ ํ•„๋“œ ๋“ฑ)
  • ๋„ค๋น„๊ฒŒ์ด์…˜ ์Šคํƒ ์ œ๊ฑฐ ์ปค์Šคํ…€ ์ƒ๋™
import SwiftUI

struct RoundedShape: Shape {
    var corners: UIRectCorner
    func path(in rect: CGRect) -> Path {
        let path = UIBezierPath(roundedRect: rect, byRoundingCorners: corners, cornerRadii: CGSize(width: 80, height: 80))
        return Path(path.cgPath)
    }
}
  • ์ปค์Šคํ…€ ๋„ํ˜•
import SwiftUI

struct CustomInputField: View {
    let imageName: String
    let placeholderText: String
    @Binding var text: String
    var body: some View {
        VStack {
            HStack {
                Image(systemName: imageName)
                    .resizable()
                    .scaledToFit()
                    .frame(width: 20, height: 20)
                    .foregroundColor(Color(.darkGray))
                TextField(placeholderText, text: $text)
            }
            
            Divider()
                .background(Color(.darkGray))
        }
    }
}
  • ์ปค์Šคํ…€ ํ…์ŠคํŠธ ํ•„๋“œ UI ๊ตฌํ˜„
import SwiftUI

struct AuthenticationHeaderView: View {
    let title: String
    var body: some View {
        VStack(alignment: .leading) {
            HStack { Spacer() }
            Text(title)
                .font(.largeTitle)
                .fontWeight(.semibold)
        }
        .frame(height: 260)
        .padding(.leading)
        .background(Color(.systemBlue))
        .foregroundColor(.white)
        .clipShape(RoundedShape(corners: [.bottomRight]))
    }
}
  • ์ปค์Šคํ…€ ๋„ํ˜•์„ ์‚ฌ์šฉ ํŠน์ • ํ…์ŠคํŠธ๋ฅผ ํ‘œ์‹œํ•˜๋Š” ํ—ค๋” ๋ทฐ UI

๊ตฌํ˜„ ํ™”๋ฉด

profile
JUST DO IT
post-custom-banner

0๊ฐœ์˜ ๋Œ“๊ธ€