Toggles and Stepper Controls

Implementing a Stepper  

Let’s start with implementing a Stepper. The Stepper can be used by the user to indicate how much of the requested food he wants to order.

For keeping track of this amount, we create a corresponding State property above our OrderForm’s body and assign it to 1.

 @State var orderAmount = 1

Now, we can insert a Stepper control into our OrderForm’s body. We need to provide the Stepper with a range of values between which the user can choose. 

var body: some View {
    Stepper(value: $orderAmount, in: 1...10) {
            
    }
}

Next, we wrap a Text view into the Stepper to indicate what amount of food the user has selected.

Stepper(value: $orderAmount, in: 1...10) {
    Text("Quantity: \(orderAmount)")
}

Let’s see if this works by starting a Live preview and tapping on the Stepper. Whenever you click on the minus or plus icon of the Stepper, you decrease or increase the value assigned to the orderAmount State. Every time this happens, the OrderForm‘s body gets rebuilt including the Text wrapped inside the Stepper.

We want to apply some padding to both views – the Stepper and the embedded Text – and add a separator line below it. We could do this manually, but fortunately, there is a much easier way: Wrapping the Toggle into a Form.

A Form groups controls and other views in a manner you perhaps know from the iOS system’s settings app.

So, let’s wrap the Stepper into a Form:

Form {
    Stepper(value: $orderAmount, in: 1...10) {
        Text("Quantity: \(orderAmount)")
    }
}

This automatically adjusts the layout for our control views and the related Text view.

Working with Toggles

Let’s continue with implementing a Toggle. By using this Toggle, the user can indicate whether he has a special request for his order or not. If this is the case, we want to present a TextField where the user can enter his special request.

To know if the user has a special request or not, we declare another State property above our OrderForm’s body:

@State var specialRequest = false

Next, we insert a Toggle view into our Form by binding it to the declared State and wrapping a Text view into it.

Toggle(isOn: $specialRequest) {
    Text("Any special requests?")
}

At this point, you can notice that in Forms, we don’t need to use VStacks for stacking views along the vertical axis.

When the Toggle is turned on, equivalent to the specialRequest State being assigned to true, we want to present a TextField below the Toggle row.

We do this by inserting a conditional statement based on the value assigned to the specialRequest State.

Toggle(isOn: $specialRequest) {
    Text("Any special requests?")
}
if specialRequest {
    TextField("Enter your request", text: <#T##Binding<String>#>)
}

Next, we create another State property for keeping track of the user’s input. We bind this State to our TextField.

struct OrderForm: View {
    
    @State var orderAmount = 1
    
    @State var specialRequest = false
    @State var specialRequestInput = ""
    
    var body: some View {
        Form {
            Stepper(value: $orderAmount, in: 1...10) {
                Text("Quantity: \(orderAmount)")
            }
            Toggle(isOn: $specialRequest) {
                Text("Any special requests?")
            }
            if specialRequest {
                TextField("Enter your request", text: $specialRequestInput)
            }
        }
    }
}

Let’s see if that works by starting a Live preview. When we tap on the Toggle, the specialRequest State gets assigned to true which causes the ContentView’s body to refresh. Then, the conditional statement gets executed which results in the TextField showing up. When we tap on the Toggle again, the State gets false again, which causes the TextField to collapse.

By default, controls such as our Toggle have a blue accent color. However, we can easily change this. To do this, we use the .toggleStyle modifier. With this modifier, we can specify a custom ToggleStyle for our Toggle. In our app, we want to use the standard SwitchToggleStyle but give it a yellow tint.

Toggle(isOn: $specialRequest) {
    Text("Any special requests?")
}
    .toggleStyle(SwitchToggleStyle(tint: .orange))

To see what else you can do with your own ToggleStyles, check out this Instagram post from us!

4 replies on “Toggles and Stepper Controls”

Hi,
You have defined :
@State var specialRequests = false
later you use it in :
Toggle(isOn: $specialRequest) {
Text(“Any special requests?”)
}
the last character s is missing.
for de rest a nice course 🙂

When entering the initalization parameters Stepper, why does value take $orderAmount as input while Text() accept orderAmount as a value? aren’t they all same parameters?

This is because the “value” parameter of a Stepper only accepts an Integer. A Text view only accepts a String. This is why we need to embed the orderAmount in a String first (String Interpolation)

Leave a Reply

Your email address will not be published. Required fields are marked *