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

Stacking up buttons

Paul Hudson    @twostraws   

We’re going to start our app by building the basic UI structure, which will be two labels telling the user what to do, then three image buttons showing three world flags.

First, find the assets for this project and drag them into your asset catalog. That means opening Assets.xcassets in Xcode, then dragging in the flag images from the project2-files folder. You’ll notice that the images are named after their country, along with either @2x or @3x – these are images at double resolution and triple resolution to handle different types of iPhone screen.

Next, we need two properties to store our game data: an array of all the country images we want to show in the game, plus an integer storing which country image is correct.

var countries = ["Estonia", "France", "Germany", "Ireland", "Italy", "Nigeria", "Poland", "Spain", "UK", "Ukraine", "US"]
var correctAnswer = Int.random(in: 0...2)

The Int.random(in:) method automatically picks a random number, which is perfect here – we’ll be using that to decide which country flag should be tapped.

Inside our body, we need to lay out our game prompt in a vertical stack, so let’s start with that:

var body: some View {
    VStack {
        Text("Tap the flag of")
        Text(countries[correctAnswer])
    }
}

Below there we want to have our tappable flag buttons, and while we could just add them to the same VStack we can actually create a second VStack so that we have more control over the spacing.

The VStack we just created above holds two text views and has no spacing, but the flags are going to have 30 points of spacing between them so it looks better.

So, we're going to wrap our previous VStack with another one, this time with a spacing value of 30, then add a new ForEach loop:

VStack(spacing: 30) {
    VStack {
        Text("Tap the flag of")
        Text(countries[correctAnswer])
    }

    ForEach(0..<3) { number in
        Button {
           // flag was tapped
        } label: {
            Image(countries[number])
        }
    }
}

Having two vertical stacks like this allows us to position things more precisely: the outer stack will space its views out by 30 points each, whereas the inner stack has no custom spacing.

That’s enough to give you a basic idea of our user interface, and already you’ll see it doesn’t look great – some flags have white in them, which blends into the background, and all the flags are centered vertically on the screen.

We’ll come back to polish the UI later, but for now let’s put in a blue background color to make the flags easier to see. Because this means putting something behind our outer VStack, we need to use a ZStack as well. Yes, we’ll have a VStack inside another VStack inside a ZStack, and that is perfectly normal.

Start by putting a ZStack around your outer VStack, like this:

var body: some View {
    ZStack {
        // previous VStack code
    }
}

Now put this just inside the ZStack, so it goes behind the outer VStack:

Color.blue
    .ignoresSafeArea()

That .ignoresSafeArea() modifier ensures the color goes right to the edge of the screen.

Now that we have a darker background color, we should give the text something brighter so that it stands out better:

Text("Tap the flag of")
    .foregroundStyle(.white)

Text(countries[correctAnswer])
    .foregroundStyle(.white)

This design is not going to set the world alight, but it’s a solid start!

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

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.