How to create and use toggle in SwiftUI

A toggle in SwiftUI is a control which can go between on and off states and it’s equivalent to UISwitch in UIKit. In this tutorial we’re going to learn how to create a toggle and use it in various examples. We’re going to update a view (show/hide an image) based on a toggle state, create custom toggle labels and adapt toggle’s border color based on its state.

In order to create a toggle, you need to define it with an isOn boolean binding which holds the on/off state. The body of the toggle is a view which defines its label.

Toggle with default label

In the following example, we’re going to create a toggle with a text label which controls whether the sound is on or off. If the toggle is on, then the app will display a speaker icon. If it’s off, then it will display a crossed out version of the speaker icon.

Take a look at the complete code:

struct ContentView: View {
    @State var isSoundOn: Bool = true
    
    var body: some View {
        VStack {
            Toggle(isOn: $isSoundOn) {
                Text("Sound")
            }
            
            Image(systemName: isSoundOn ? "speaker.1.fill" : "speaker.slash.fill")
                .font(.system(size: 56))
                .padding()
            
            Spacer()
        }.padding()
    }
}

The result should look like this:

SwiftUI Toggle in on and off states

In fact, if your toggle label contains just a Text view, then you can initialize it like that:

Toggle("Sound", isOn: $isSoundOn)

Toggle without a label

If you’d like to hide the label of the toggle, use labelsHidden() modifier:

Toggle("Sound", isOn: $isSoundOn).labelsHidden()

And the result will look like this:

SwiftUI Toggle with hidden label
SwiftUI Toggle with hidden label

Notice that the toggle with a label expands to fill the entire width of the container, placing the label and toggle on opposite ends of the view. But what if we wanted to place the label above (or below) of the toggle?

Toggle with custom label

Here is an example with a custom label above of the toggle:

VStack {
    Text("Toggle Sound")
    Toggle("Sound", isOn: $isSoundOn).labelsHidden()
}.padding()
SwiftUI toggle with label on top
SwiftUI toggle with label on top

Toggle with custom label and border

Let’s take this example even further and add a border around the toggle and update the color of the toggle label and border depending on the state of the toggle. If the toggle is on, then we’ll color the label with border in green, otherwise it’ll be colored in gray.

struct ContentView: View {
    @State var isSoundOn: Bool = true
    
    var body: some View {
        VStack {
            Text("Toggle Sound")
                .foregroundColor(isSoundOn ? .green : .gray)
            Toggle("Sound", isOn: $isSoundOn)
                .labelsHidden()
        }.padding()
        .overlay(
            RoundedRectangle(cornerRadius: 15)
                .stroke(lineWidth: 2)
                .foregroundColor(isSoundOn ? .green : .gray)
        )
    }
}

Final result:

SwiftUI Toggle with custom label and border
SwiftUI Toggle with custom label and border

Related tutorials:

Check out Apple’s official documentation of Toggle.