Day 15 – Forms, TextFields, and User Input
T
Tuan Beo

Day 15 – Forms, TextFields, and User Input

Learn how to use forms and text fields to collect user input and manage it in your SwiftUI app.

1️⃣ Forms in SwiftUI

Form automatically applies grouped styling for data entry screens.

Form {
    Section(header: Text("Profile Info")) {
        TextField("Name", text: $name)
        SecureField("Password", text: $password)
    }
    Section {
        Toggle("Receive Notifications", isOn: $notificationsEnabled)
    }
}

2️⃣ Updating AddFriendView with Form & Validation

We’ll improve the Add Friend screen from Day 14.

import SwiftUI

struct AddFriendView: View {
    @Environment(\.dismiss) private var dismiss
    @State private var name: String = ""
    @State private var isOnline: Bool = false
    @State private var errorMessage: String?
    
    let onAdd: (Friend) -> Void
    
    var body: some View {
        NavigationStack {
            Form {
                Section("New Friend") {
                    TextField("Name", text: $name)
                        .autocorrectionDisabled()
                        .textInputAutocapitalization(.words)
                        .submitLabel(.done)
                        .onSubmit { saveFriend() }
                    
                    Toggle("Online", isOn: $isOnline)
                }
                
                if let error = errorMessage {
                    Section {
                        Text(error)
                            .foregroundStyle(.red)
                    }
                }
            }
            .navigationTitle("Add Friend")
            .toolbar {
                ToolbarItem(placement: .topBarLeading) {
                    Button("Cancel") { dismiss() }
                }
                ToolbarItem(placement: .topBarTrailing) {
                    Button("Save") { saveFriend() }
                        .disabled(name.trimmingCharacters(in: .whitespaces).isEmpty)
                }
            }
        }
    }
    
    private func saveFriend() {
        let trimmedName = name.trimmingCharacters(in: .whitespaces)
        guard !trimmedName.isEmpty else {
            errorMessage = "Name cannot be empty"
            return
        }
        
        onAdd(.init(name: trimmedName, isOnline: isOnline))
        dismiss()
    }
}


3️⃣ Key improvements from Day 14

  • .autocorrectionDisabled() → prevents unwanted spelling corrections.

  • .textInputAutocapitalization(.words) → capitalizes each word in names.

  • .submitLabel(.done) → changes keyboard button label to “Done”.

  • .onSubmit → triggers save when pressing “Done” on keyboard.

  • Validation → shows error message if field is empty.


4️⃣ Adding Secure Input (optional)

If you were building a login screen:

SecureField("Password", text: $password)

This hides the entered text with dots.

🛠 Practice

  1. Add a TextField for “Nickname” that’s optional.

  2. Add a DatePicker for “Birthday” and display it in FriendDetailView.

  3. Prevent adding more than 1 friend with the same name (check in onAdd).

  4. Disable the Save button if name is empty and online status is false.

Comments