Creating a Stylish Login UI with SwiftUI in Xcode 14
Written on
Chapter 1: Introduction
Welcome to another SwiftUI tutorial! I hope this message finds you well. In today's session, we will dive into the design process of a Login UI using SwiftUI 4 and Xcode 14.
Let's kick things off by launching Xcode 14. We'll begin by adding some colors to the Asset catalog that will be utilized in our UI. For our text colors, we will be using standard white and black, along with shades of blue.
Fantastic! Now that we have our colors set, it's time to delve into the exciting part—creating a custom button modifier and a personalized text field.
Section 1.1: Custom Button Modifier
import SwiftUI
struct CustomButtonModifier: ViewModifier {
func body(content: Content) -> some View {
return content
.foregroundColor(.white)
.padding(.vertical)
.padding(.horizontal, 35)
.background(
LinearGradient(gradient: .init(colors: [Color("blue-light"), Color("blue")]), startPoint: .leading, endPoint: .trailing))
.clipShape(Capsule())
}
}
Section 1.2: Custom Text Field
import SwiftUI
struct CustomTextField: View {
var image: String
var title: String
@Binding var value: String
var animation: Namespace.ID
var body: some View {
VStack(spacing: 6) {
HStack(alignment: .bottom) {
Image(systemName: image)
.font(.system(size: 22))
.foregroundColor(value.isEmpty ? .gray : .primary)
.frame(width: 35)
VStack(alignment: .leading, spacing: 6) {
if !value.isEmpty {
Text(title)
.font(.caption)
.fontWeight(.heavy)
.foregroundColor(.gray)
.matchedGeometryEffect(id: title, in: animation)
}
ZStack(alignment: .leading) {
if value.isEmpty {
Text(title)
.font(.caption)
.fontWeight(.heavy)
.foregroundColor(.gray)
.matchedGeometryEffect(id: title, in: animation)
}
if title == "PASSWORD" {
SecureField("", text: $value)} else {
TextField("", text: $value)
.keyboardType(title == "PHONE NUMBER" ? .numberPad : .default)}
}
}
}
if value.isEmpty {
Divider()}
}
.padding(.horizontal)
.padding(.vertical, 10)
.background(Color("txt").opacity(value.isEmpty ? 0 : 1))
.cornerRadius(8)
.shadow(color: Color.black.opacity(value.isEmpty ? 0 : 0.1), radius: 5, x: 5, y: 5)
.shadow(color: Color.black.opacity(value.isEmpty ? 0 : 0.05), radius: 5, x: -5, y: -5)
.padding(.horizontal)
.padding(.top)
.animation(.linear)
}
}
Chapter 2: Building the Signup UI
Now, let's focus on creating the Signup UI. We will utilize the @Namespace protocol and ScrollView.
What is the @Namespace Protocol?
It serves as a dynamic property type that grants access to a namespace defined by the persistent identity of the containing object, such as a view.
What is a ScrollView in SwiftUI?
The ScrollView allows the display of content that can be scrolled, either vertically or horizontally, based on user interactions.
import SwiftUI
struct Register: View {
@State var email = ""
@State var password = ""
@State var name = ""
@State var number = ""
@Binding var show: Bool
@Namespace var animation
var body: some View {
ScrollView(.vertical, showsIndicators: false) {
VStack {
HStack {
Button(action: { show.toggle() }) {
Image(systemName: "arrow.left")
.font(.largeTitle)
.foregroundColor(.gray)
}
Spacer()
}
.padding()
HStack {
Text("Create Account")
.font(.system(size: 40))
.fontWeight(.heavy)
.foregroundColor(.primary)
Spacer()
}
.padding()
CustomTextField(image: "person", title: "FULL NAME", value: $name, animation: animation)
CustomTextField(image: "envelope", title: "EMAIL", value: $email, animation: animation)
.padding(.top, 5)CustomTextField(image: "lock", title: "PASSWORD", value: $password, animation: animation)
.padding(.top, 5)CustomTextField(image: "phone.fill", title: "PHONE NUMBER", value: $number, animation: animation)
.padding(.top, 5)
HStack {
Spacer()
Button(action: {}) {
HStack(spacing: 10) {
Text("SIGN UP")
.fontWeight(.heavy)Image(systemName: "arrow.right")
.font(.title2)}
.modifier(CustomButtonModifier())
}
}
.padding()
HStack {
Text("Already have an account?")
.fontWeight(.heavy)
.foregroundColor(.gray)
Button(action: { show.toggle() }) {
Text("sign in")
.fontWeight(.heavy)
.foregroundColor(Color("blue"))
}
}
.padding()
}
}
.navigationBarHidden(true)
.navigationBarBackButtonHidden(true)
}
}
Creating the Login View
Next, we will work on the Login view using NavigationLink.
Chapter 3: Connecting Everything in the Content View
import SwiftUI
struct ContentView: View {
var body: some View {
NavigationView {
LoginView()
.navigationBarHidden(true)
.navigationBarBackButtonHidden(true)
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()}
}
Conclusion
Awesome! We have successfully completed the creation of a Login UI using SwiftUI 4 and Xcode 14. We explored the implementation of NavigationLink, as well as how to create custom components such as CustomButtonModifier and CustomTextField. With this newfound knowledge, you are well-equipped to build some impressive applications.
If you wish to access the complete source code for this tutorial, feel free to reach out! I hope you found this tutorial enjoyable. For more SwiftUI tutorials, don't forget to check out our channel for additional exciting content and stay tuned for upcoming sessions.
In this video, we demonstrate how to create a simple login screen for iPhone using Xcode and SwiftUI.
Watch as we develop a complex login application for iPadOS with SwiftUI and Xcode 14 WWDC23.