SwiftUI
Apple's modern declarative UI framework
🎨 What is SwiftUI?
SwiftUI is Apple's modern framework for building user interfaces across all Apple platforms. It uses declarative syntax to create beautiful, responsive UIs with less code, automatic dark mode support, and seamless animations.
import SwiftUI
struct ContentView: View {
var body: some View {
VStack {
Text("Hello, SwiftUI!")
.font(.largeTitle)
.foregroundColor(.blue)
Button("Tap Me") {
print("Button tapped!")
}
}
}
}
Key SwiftUI Concepts
Views
Building blocks of SwiftUI interfaces
struct MyView: View {
var body: some View {
Text("Hello World")
}
}
State
Managing data that changes over time
@State private var count = 0
Button("Count: \(count)") {
count += 1
}
Layout
Arranging views with stacks and grids
VStack {
Text("Top")
HStack {
Text("Left")
Text("Right")
}
}
Modifiers
Styling and configuring views
Text("Styled")
.font(.title)
.foregroundColor(.red)
.padding()
🔹 Basic Views and Layout
Create interfaces using fundamental SwiftUI views:
import SwiftUI
struct BasicLayoutView: View {
var body: some View {
VStack(spacing: 20) {
// Text views
Text("Welcome to SwiftUI")
.font(.largeTitle)
.fontWeight(.bold)
Text("Build amazing apps")
.font(.subheadline)
.foregroundColor(.secondary)
// Image
Image(systemName: "swift")
.font(.system(size: 50))
.foregroundColor(.orange)
// Horizontal stack
HStack(spacing: 15) {
Button("Cancel") {
print("Cancel tapped")
}
.foregroundColor(.red)
Button("Save") {
print("Save tapped")
}
.foregroundColor(.blue)
}
// Spacer pushes content up
Spacer()
}
.padding()
}
}
🔹 State Management
Handle changing data with state properties:
import SwiftUI
struct CounterView: View {
@State private var count = 0
@State private var name = ""
@State private var isToggled = false
var body: some View {
VStack(spacing: 20) {
Text("Count: \(count)")
.font(.title)
HStack {
Button("-") {
count -= 1
}
.font(.title)
Button("+") {
count += 1
}
.font(.title)
}
TextField("Enter your name", text: $name)
.textFieldStyle(RoundedBorderTextFieldStyle())
.padding(.horizontal)
if !name.isEmpty {
Text("Hello, \(name)!")
.font(.headline)
}
Toggle("Enable notifications", isOn: $isToggled)
.padding(.horizontal)
if isToggled {
Text("Notifications enabled")
.foregroundColor(.green)
}
}
.padding()
}
}
🔹 Lists and Navigation
Create scrollable lists and navigation between views:
import SwiftUI
struct Item: Identifiable {
let id = UUID()
let name: String
let description: String
}
struct ListView: View {
let items = [
Item(name: "iPhone", description: "Apple's smartphone"),
Item(name: "iPad", description: "Apple's tablet"),
Item(name: "MacBook", description: "Apple's laptop"),
Item(name: "Apple Watch", description: "Apple's smartwatch")
]
var body: some View {
NavigationView {
List(items) { item in
NavigationLink(destination: DetailView(item: item)) {
VStack(alignment: .leading) {
Text(item.name)
.font(.headline)
Text(item.description)
.font(.subheadline)
.foregroundColor(.secondary)
}
}
}
.navigationTitle("Products")
}
}
}
struct DetailView: View {
let item: Item
var body: some View {
VStack(spacing: 20) {
Image(systemName: "star.fill")
.font(.system(size: 100))
.foregroundColor(.yellow)
Text(item.name)
.font(.largeTitle)
.fontWeight(.bold)
Text(item.description)
.font(.body)
.multilineTextAlignment(.center)
.padding()
Spacer()
}
.navigationTitle(item.name)
.navigationBarTitleDisplayMode(.inline)
}
}
🔹 Forms and User Input
Create forms for user data collection:
import SwiftUI
struct UserProfileForm: View {
@State private var firstName = ""
@State private var lastName = ""
@State private var email = ""
@State private var birthDate = Date()
@State private var favoriteColor = Color.blue
@State private var newsletter = false
@State private var experience = "Beginner"
let experienceLevels = ["Beginner", "Intermediate", "Advanced", "Expert"]
var body: some View {
NavigationView {
Form {
Section(header: Text("Personal Information")) {
TextField("First Name", text: $firstName)
TextField("Last Name", text: $lastName)
TextField("Email", text: $email)
.keyboardType(.emailAddress)
.autocapitalization(.none)
}
Section(header: Text("Details")) {
DatePicker("Birth Date", selection: $birthDate, displayedComponents: .date)
ColorPicker("Favorite Color", selection: $favoriteColor)
Picker("Experience Level", selection: $experience) {
ForEach(experienceLevels, id: \.self) { level in
Text(level)
}
}
.pickerStyle(MenuPickerStyle())
}
Section(header: Text("Preferences")) {
Toggle("Subscribe to newsletter", isOn: $newsletter)
}
Section {
Button("Save Profile") {
saveProfile()
}
.disabled(firstName.isEmpty || lastName.isEmpty)
}
}
.navigationTitle("Profile")
}
}
func saveProfile() {
print("Saving profile for \(firstName) \(lastName)")
// Save logic here
}
}
🔹 Animations and Transitions
Add smooth animations to enhance user experience:
import SwiftUI
struct AnimationView: View {
@State private var isExpanded = false
@State private var rotationAngle = 0.0
@State private var scale = 1.0
@State private var offset = CGSize.zero
var body: some View {
VStack(spacing: 30) {
// Expanding/Contracting View
RoundedRectangle(cornerRadius: 10)
.fill(Color.blue)
.frame(width: isExpanded ? 200 : 100,
height: isExpanded ? 200 : 100)
.animation(.easeInOut(duration: 0.5), value: isExpanded)
.onTapGesture {
isExpanded.toggle()
}
// Rotating View
Image(systemName: "arrow.clockwise")
.font(.system(size: 50))
.rotationEffect(.degrees(rotationAngle))
.animation(.linear(duration: 1), value: rotationAngle)
.onTapGesture {
rotationAngle += 360
}
// Scaling View
Circle()
.fill(Color.green)
.frame(width: 80, height: 80)
.scaleEffect(scale)
.animation(.spring(response: 0.5, dampingFraction: 0.6), value: scale)
.onTapGesture {
scale = scale == 1.0 ? 1.5 : 1.0
}
// Moving View
RoundedRectangle(cornerRadius: 10)
.fill(Color.red)
.frame(width: 60, height: 60)
.offset(offset)
.animation(.easeInOut(duration: 0.8), value: offset)
.onTapGesture {
offset = offset == .zero ? CGSize(width: 100, height: 0) : .zero
}
Text("Tap the shapes to animate!")
.font(.caption)
.foregroundColor(.secondary)
}
.padding()
}
}
🔹 SwiftUI Best Practices
Guidelines for building great SwiftUI apps:
✅ Do:
- Break down complex views into smaller, reusable components
- Use @State for local data and @ObservedObject for shared data
- Leverage preview providers for rapid development
- Use semantic colors for automatic dark mode support
- Apply modifiers in logical order (layout first, then styling)
❌ Don't:
- Put business logic directly in view bodies
- Create massive view structs - extract subviews
- Overuse animations - keep them purposeful
- Ignore accessibility - add labels and hints