UPGRADE YOUR SKILLS: Learn advanced Swift and SwiftUI on Hacking with Swift+! >>

Building a basic layout

Paul Hudson    @twostraws   

This app is going to allow user input with a date picker and two steppers, which combined will tell us when they want to wake up, how much sleep they usually like, and how much coffee they drink.

So, please start by adding three properties that let us store the information for those controls:

@State private var wakeUp = Date.now
@State private var sleepAmount = 8.0
@State private var coffeeAmount = 1

Inside our body we’re going to place three sets of components wrapped in a VStack and a NavigationStack, so let’s start with the wake up time. Replace the default “Hello World” text view with this:

NavigationStack {
    VStack {
        Text("When do you want to wake up?")
            .font(.headline)

        DatePicker("Please enter a time", selection: $wakeUp, displayedComponents: .hourAndMinute)
            .labelsHidden()

        // more to come
    }
}

We’ve asked for .hourAndMinute configuration because we care about the time someone wants to wake up and not the day, and with the labelsHidden() modifier we don’t get a second label for the picker – the one above is more than enough.

Next we’re going to add a stepper to let users choose roughly how much sleep they want. By giving this thing an in range of 4...12 and a step of 0.25 we can be sure they’ll enter sensible values, but we can combine that with the formatted() method so we see numbers like “8” and not “8.000000”.

Add this code in place of the // more to come comment”

Text("Desired amount of sleep")
    .font(.headline)

Stepper("\(sleepAmount.formatted()) hours", value: $sleepAmount, in: 4...12, step: 0.25)

Finally we’ll add one last stepper and label to handle how much coffee they drink. This time we’ll use the range of 1 through 20 – because surely 20 coffees a day is enough for anyone?

Add these inside the VStack, below the previous views:

Text("Daily coffee intake")
    .font(.headline)

Stepper("\(coffeeAmount) cup(s)", value: $coffeeAmount, in: 1...20)

The final thing we need is a button to let users calculate the best time they should go to sleep. We could do that with a simple button at the end of the VStack, but I think it works better to add a button directly to the navigation bar.

First we need a method for the button to call, so add an empty calculateBedtime() method like this:

func calculateBedtime() {
}

Now we need to use the toolbar() modifier to add a button to the navigation bar. While we’re here, we might as well also use navigationTitle() to put some text at the top.

So, add these modifiers to the VStack:

.navigationTitle("BetterRest")
.toolbar {
    Button("Calculate", action: calculateBedtime)
}

Tip: Our button will automatically be placed in the top-right corner for left-to-right languages such as English, but will automatically move to the other side for right-to-left languages.

That won’t do anything yet because calculateBedtime() is empty, but at least our UI is good enough for the time being.

BUILD THE ULTIMATE PORTFOLIO APP Most Swift tutorials help you solve one specific problem, but in my Ultimate Portfolio App series I show you how to get all the best practices into a single app: architecture, testing, performance, accessibility, localization, project organization, and so much more, all while building a SwiftUI app that works on iOS, macOS and watchOS.

Get it on Hacking with Swift+

Sponsor Hacking with Swift and reach the world's largest Swift community!

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.8/5

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.