WWDC24 SALE: Save 50% on all my Swift books and bundles! >>

Adding a segmented control for tip percentages

Paul Hudson    @twostraws   

Now we’re going to add a second picker view to our app, but this time we want something slightly different: we want a segmented control. This is a specialized kind of picker that shows a handful of options in a horizontal list, and it works great when you have only a small selection to choose from.

Our form already has two sections: one for the amount and number of people, and one where we’ll show the final result – it’s just showing checkAmount for now, but we’re going to fix it soon.

In the middle of those two sections I’d like you to add a third to show tip percentages:

Section {
    Picker("Tip percentage", selection: $tipPercentage) {
        ForEach(tipPercentages, id: \.self) {
            Text($0, format: .percent)
        }
    }
}

That loops over all the options in our tipPercentages array, converting each one into a text view with the .percent format. Just like the previous picker, SwiftUI will convert that to a single row in our list, and present a pop-up menu of options when it’s tapped.

Here, though, I want to show you how to use a segmented control instead, because it looks much better. So, please add this modifier to the tip picker:

.pickerStyle(.segmented)

That should go at the end of the picker’s closing brace, like this:

Section {
    Picker("Tip percentage", selection: $tipPercentage) {
        ForEach(tipPercentages, id: \.self) {
            Text($0, format: .percent)
        }
    }
    .pickerStyle(.segmented)
}

If you run the program now you’ll see things are starting to come together: users can now enter the amount on their check, select the number of people, and select how much tip they want to leave – not bad!

But things aren’t quite what you think. One problem app developers face is that we take for granted that our app does what we intended it to do – we designed it to solve a particular problem, so we automatically know what everything means.

Try to look at our user interface with fresh eyes, if you can:

  • “Amount” makes sense – it’s a box users can type a number into.
  • “Number of people” is also pretty self-explanatory.
  • The label at the bottom is where we’ll show the total, so right now we can ignore that.
  • That middle section, though – what are those percentages for?

Yes, we know they are to select how much tip to leave, but that isn’t obvious on the screen. We can – and should do better.

One option is to add another text view directly before the segmented control, which we could do like this:

Section {
    Text("How much tip do you want to leave?")

    Picker("Tip percentage", selection: $tipPercentage) {
        ForEach(tipPercentages, id: \.self) {
            Text($0, format: .percent)
        }
    }
    .pickerStyle(.segmented)
}

That works OK, but it doesn’t look great – it looks like it’s an item all by itself, rather than a label for the segmented control.

A much better idea is to modify the section itself: SwiftUI lets us add views to the header and footer of a section, which in this instance we can use to add a small explanatory prompt. In fact, we can use the same text we just created, just moved to be the section header rather than a loose label inside it.

Here’s how that looks in code:

Section("How much tip do you want to leave?") {
    Picker("Tip percentage", selection: $tipPercentage) {
        ForEach(tipPercentages, id: \.self) {
            Text($0, format: .percent)
        }
    }
    .pickerStyle(.segmented)
}

It’s a small change to the code, but I think the end result looks a lot better – the text now looks like a prompt for the segmented control directly below it.

Save 50% in my WWDC sale.

SAVE 50% To celebrate WWDC24, all our books and bundles are half price, so you can take your Swift knowledge further without spending big! Get the Swift Power Pack to build your iOS career faster, get the Swift Platform Pack to builds apps for macOS, watchOS, and beyond, or get the Swift Plus Pack to learn advanced design patterns, testing skills, and more.

Save 50% on all our books and bundles!

BUY OUR BOOKS
Buy Pro Swift Buy Pro SwiftUI Buy Swift Design Patterns Buy Testing Swift Buy Hacking with iOS Buy Swift Coding Challenges Buy Swift on Sundays Volume One Buy Server-Side Swift Buy Advanced iOS Volume One Buy Advanced iOS Volume Two Buy Advanced iOS Volume Three Buy Hacking with watchOS Buy Hacking with tvOS Buy Hacking with macOS Buy Dive Into SpriteKit Buy Swift in Sixty Seconds Buy Objective-C for Swift Developers Buy Beyond Code

Was this page useful? Let us know!

Average rating: 4.9/5

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.