Show and Hide Sections in SwiftUI Forms

DevTechie Inc
May 11, 2023

Forms in SwiftUI are used to collect information from users. Long forms are discouraging and show a lack of structure, so its a good idea to display sections of the form as needed.

In this article, we will explore a way to show/hide sections of a form.

Let’s get started with a simple form.

struct DevTechieShowHideForm: View {
    @State private var firstName: String = ""
    @State private var lastName: String = ""
    @State private var street: String = ""
    @State private var city: String = ""
    @State private var zip: String = ""
    @State private var lengthAtAddress: Int = 1
    @State private var email: String = ""
    @State private var username: String = ""
    @State private var password: String = ""
    
    var body: some View {
        NavigationStack {
            Form {
                Section(header: Text("Personal Info")) {
                    TextField("First name", text: $firstName)
                    TextField("Last name", text: $lastName)
                }
                Section(header: Text("Current Address Info")) {
                    TextField("Street name", text: $street)
                    TextField("City name", text: $city)
                    TextField("Zip Code", text: $zip)
                    Stepper("Length at current address: \(lengthAtAddress) years", value: $lengthAtAddress, in: 1...99)
                }
                Section(header: Text("Login Info")) {
                    TextField("Email", text: $email)
                    TextField("Username", text: $username)
                    SecureField("Password", text: $password)
                }
                
                Button("Submit") {
                    
                }
            }
            .navigationTitle("DevTechie Sign Up")
        }
    }
}

Let’s add logic where if user has stayed in at the current address for less than 5 years, the app should show a section to collect previous address information.

We will start by adding State variables to hold previous address information.

// previous address info
    @State private var prevStreet: String = ""
    @State private var prevCity: String = ""
    @State private var prevZip: String = ""

Let’s add an if-conditional logic to check if the lengthAtAddress value is less than five years.

if lengthAtAddress < 5 {
    Section(header: Text("Previous Address Info")) {
        TextField("Previous street name", text: $prevStreet)
        TextField("Previous city name", text: $prevCity)
        TextField("Previous zip code", text: $prevZip)
    }
}

Let’s also update the default value for lengthAtAddress to be 5 so the section is hidden when the form is shown to the user.

@State private var lengthAtAddress: Int = 5

The complete code should look like this.

struct DevTechieShowHideForm: View {
    @State private var firstName: String = ""
    @State private var lastName: String = ""
    @State private var street: String = ""
    @State private var city: String = ""
    @State private var zip: String = ""
    @State private var lengthAtAddress: Int = 5
    @State private var email: String = ""
    @State private var username: String = ""
    @State private var password: String = ""
    
    // previous address info
    @State private var prevStreet: String = ""
    @State private var prevCity: String = ""
    @State private var prevZip: String = ""
    
    var body: some View {
        NavigationStack {
            Form {
                Section(header: Text("Personal Info")) {
                    TextField("First name", text: $firstName)
                    TextField("Last name", text: $lastName)
                }
                Section(header: Text("Current Address Info")) {
                    TextField("Street name", text: $street)
                    TextField("City name", text: $city)
                    TextField("Zip Code", text: $zip)
                    Stepper("Length at current address: \(lengthAtAddress) years", value: $lengthAtAddress, in: 1...99)
                }
                if lengthAtAddress < 5 {
                    Section(header: Text("Previous Address Info")) {
                        TextField("Previous street name", text: $prevStreet)
                        TextField("Previous city name", text: $prevCity)
                        TextField("Previous zip code", text: $prevZip)
                    }
                }
                Section(header: Text("Login Info")) {
                    TextField("Email", text: $email)
                    TextField("Username", text: $username)
                    SecureField("Password", text: $password)
                }
                
                Button("Submit") {
                    
                }
            }
            .navigationTitle("DevTechie Sign Up")
        }
    }
}

Build and run

Notice that the view just appears without much indication. We can fix that by adding an animation modifier.

struct DevTechieShowHideForm: View {
    @State private var firstName: String = ""
    @State private var lastName: String = ""
    @State private var street: String = ""
    @State private var city: String = ""
    @State private var zip: String = ""
    @State private var lengthAtAddress: Int = 5
    @State private var email: String = ""
    @State private var username: String = ""
    @State private var password: String = ""
    
    // previous address info
    @State private var prevStreet: String = ""
    @State private var prevCity: String = ""
    @State private var prevZip: String = ""
    
    var body: some View {
        NavigationStack {
            Form {
                Section(header: Text("Personal Info")) {
                    TextField("First name", text: $firstName)
                    TextField("Last name", text: $lastName)
                }
                Section(header: Text("Current Address Info")) {
                    TextField("Street name", text: $street)
                    TextField("City name", text: $city)
                    TextField("Zip Code", text: $zip)
                    Stepper("Length at current address: \(lengthAtAddress) years", value: $lengthAtAddress, in: 1...99)
                }
                if lengthAtAddress < 5 {
                    Section(header: Text("Previous Address Info")) {
                        TextField("Previous street name", text: $prevStreet)
                        TextField("Previous city name", text: $prevCity)
                        TextField("Previous zip code", text: $prevZip)
                    }
                }
                Section(header: Text("Login Info")) {
                    TextField("Email", text: $email)
                    TextField("Username", text: $username)
                    SecureField("Password", text: $password)
                }
                
                Button("Submit") {
                    
                }
            }
            .animation(.easeInOut, value: lengthAtAddress)
            .navigationTitle("DevTechie Sign Up")
        }
    }
}

Build and run to hide/show our section with an animation.