Group Group Group Group Group Group Group Group Group Group Shape Group Group Group Group Group Group Group Group Group Group Group Group Group Group Group Group Group Group Group Group Group Group Group Group Group Group Group Group Group Group Group Group Group Group Group Group
Open menu
The new raywenderlich.com
Open menu
The new raywenderlich.com
Learn

iOS & Swift

Start here Programs Learning paths Videos Articles Books

Android & Kotlin

Start here Programs Learning paths Videos Articles Books

Flutter & Dart

Start here Learning paths Videos Articles Books
Server-side Swift
Game Tech
All Videos
All Articles
All Books
Browse the entire library
iOS & Swift
Programs Mentor-supported learning with certificates Learning Paths Curated collections of courses Videos In-depth video courses Articles Short, focused written tutorials Books Full-length coding books All Tutorials Browse the entire iOS & Swift library
Personal
Individual Subscriptions Live Bootcamps On-Demand Bootcamps
Business
Team & Enterprise subscriptions Workshops
Resources
Community Forums Newsletter Support Discord
Sign in Start for free
Search
Toggle night mode
Sign in Start for free
##company##
##description##
##callToAction##
`; ['#carbon-hero-ad'].forEach((target) => { // Initialise each of the native ads _bsa.init('custom', 'CESIC5QL', 'wwwraywenderlichcom', { target: target, template: carbonTemplate, }); }); } } // Run this on load document.addEventListener('turbo:load', carbonAdsHandler); // But need to remove it for turbo purposes. Otherwise we just keep adding ads document.addEventListener('turbo:visit', () => { // Before we go somewhere else, let's not add the same handler again document.removeEventListener('turbo:load', carbonAdsHandler); });
Home
...
iOS & Swift Tutorials
SwiftUI: Getting Started
Home
...
iOS & Swift Tutorials
SwiftUI: Getting Started

SwiftUI: Getting Started

Jun 10 2019 , Swift 5, iOS 13, Xcode 11 Swift 5, iOS 13, Xcode 11

In this SwiftUI tutorial, you’ll learn how to layout the UI by declaring and modifying views, and how to use state variables to update your UI. You’ll use Xcode’s new preview and live preview, and experience the joy of code and WYSIWYG layout that stay in sync. By Audrey Tam.

4.6 (121) · 1 Review

Download materials

Sign up/Sign in

With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!

Create account

Already a member of Kodeco? Sign in

Save for later

Sign up/Sign in

With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!

Create account

Already a member of Kodeco? Sign in

Share

Share this

Twitter

Share

Facebook

Share

Email

Share
Contents

Contents

Hide contents

SwiftUI: Getting Started

25 mins

  • Getting Started
  • Entering the New World of SwiftUI
  • Outlining Your UI
  • Filling in Your Outline
  • Using @State Variables
  • Making Reusable Views
  • Presenting an Alert
  • Previewing in Landscape
  • Where to Go From Here?
  • Contents

SwiftUI is the most exciting news since Apple announced Swift in 2014. It’s an enormous step towards Apple’s goal of getting everyone coding, simplifying the basics so you can spend more time on custom features that delight your users. Some developers have joked (?) that they might be “Sherlocked” by SwiftUI!

SwiftUI lets you ignore Interface Builder (IB) and storyboards without having to write detailed step-by-step instructions for laying out your UI. IB and Xcode were separate apps before Xcode 4, and the seams still show every time you edit the name of an IBAction or IBOutlet or delete it from your code, and your app crashes because IB doesn’t see changes to code. Or you’ve fumed about stringly-typed identifiers for segues or table view cells that you have to use in your code, but Xcode can’t check for you because they’re strings. And, while it might be faster and easier to design a new UI in a WYSIWYG editor, it’s much more efficient to copy or edit UI when it’s written out in code.

SwiftUI to the rescue! You can preview a SwiftUI view side-by-side with its code — a change to one side will update the other side, so they’re always in sync. There aren’t any identifier strings to get wrong. And it’s code, but a lot less than you’d write for UIKit, so it’s easier to understand, edit and debug. What’s not to love?

SwiftUI doesn’t replace UIKit — like Swift and Objective-C, you can use both in the same app. The SwiftUI APIs are consistent across platforms, so it will be easier to develop the same-ish app on multiple platforms using the same source code on each.

In this article, you’ll use SwiftUI to build a variation of our famous BullsEye game from iOS Apprentice.

Note: Our recently updated iOS Apprentice book starts with building the BullsEye game in SwiftUI!

You’ll learn how to layout the UI by declaring and modifying views, and how to use state variables to update your UI. You’ll use some of Xcode’s new tools, especially previews and live previews, and experience the joy of code and WYSIWYG layout that stay in sync.

If you don’t have a spare Mac, you can install Catalina on a separate APFS volume (not partition).

Note: This article assumes you’re comfortable with using Xcode to develop iOS apps. You need Xcode 11. To see the SwiftUI preview, you need macOS 10.15. SwiftUI is very new, so you also need some level of comfort using beta-like software. ;]

If you don’t have a spare Mac, you can install Catalina on a separate APFS volume (not partition).

Getting Started

Get started by downloading the materials for this article — you can find the link at the top or bottom of this article. Build and run the UIKit app in the RGBullsEye-Starter folder. This game uses three sliders — for red, green and blue values in the RGB color space — to match a target color.

I wrote this app for RWDevCon 2016 and updated the code to Swift 5 for this article. It runs in Xcode 10 and Xcode 11. In this article, you’ll use SwiftUI to create a basic version of this game.

In Xcode 11, create a new Xcode project (Shift-Command-N), select iOS â–¸ Single View App, name the project RGBullsEye, then select SwiftUI in the User Interface menu:

Save your project somewhere outside the RGBullsEye-Starter folder.

Entering the New World of SwiftUI

In the project navigator, open the RGBullsEye group to see what you got: the old AppDelegate.swift is now split into AppDelegate.swift and SceneDelegate.swift and SceneDelegate has the window:

SceneDelegate isn’t specific to SwiftUI, but this line is:

window.rootViewController = UIHostingController(rootView: ContentView())

UIHostingController creates a view controller for the SwiftUI view ContentView.

Note: UIHostingController enables you to integrate SwiftUI views into an existing app. You add a Hosting View Controller to your storyboard and create a segue to it from a UIViewController. Then Control-drag from the segue into the view controller code to create an IBSegueAction, where you specify the hosting controller’s rootView value — a SwiftUI view.

When the app starts, window displays an instance of ContentView, which is defined in ContentView.swift. It’s a struct that conforms to the View protocol:

struct ContentView: View {
  var body: some View {
    Text("Hello World")
  }
}

This is SwiftUI declaring that the body of ContentView contains a Text view that displays Hello World.

Down below struct ContentView, struct ContentView_Previews produces a view that contains an instance of ContentView.

struct ContentView_Previews: PreviewProvider {
  static var previews: some View {
    ContentView()
  }
}

This is where you can specify sample data for the preview. But where is this preview you’ve heard so much about?

There’s a big blank space next to the code, with this at the top:

Click Resume, and wait a while to see the preview:

If you still don’t see the Resume button, make sure you’re running macOS 10.15.

Note: If you don’t see the Resume button, click the editor options button, and select Editor and Canvas:

If you still don’t see the Resume button, make sure you’re running macOS 10.15.

Outlining Your UI

The one file you don’t see listed is Main.storyboard — you’re going to create your UI in SwiftUI code, keeping an eye on the preview to see what it looks like. But don’t worry — you won’t be writing hundreds of lines of code to create views!

SwiftUI is declarative: You declare how you want the UI to look, and SwiftUI converts your declarations into efficient code that gets the job done. Apple encourages you to create as many views as you need, to keep your code easy to read and maintain. Reusable, parameterized views are especially recommended — it’s just like extracting code into a function, and you’ll create one later in this article.

RGBullsEye’s UI has a lot of subviews, so you’ll first create an “outline”, using Text views as placeholders. The finished UI will look like this, with a different randomly-generated target color on the left:

Start by replacing Text("Hello World") with this:

Text("Target Color Block")

If necessary, click Resume to refresh the preview.

Now Command-Click the Text view in the preview, and select Embed in HStack:

Note: If Command-Click jumps to the definition of Text, use Control-Command-Click instead.

Notice your code updates to match:

HStack {
  Text("Target Color Block")
}

You’re using a horizontal stack here because you want to display the target and guess color blocks side by side.

Copy and paste the Text statement, then edit it so your HStack looks like the following. Notice you don’t separate the two statements with a comma — just write each on its own line:

HStack {
  Text("Target Color Block")
  Text("Guess Color Block")
}

And there it is in the preview:

Now prepare for adding the slider placeholders by embedding the HStack in a VStack — this time, Command-Click on HStack in your code:

Select Embed in VStack; new code appears, but the preview doesn’t change — you need to add views below the color blocks.

Open a new line below your HStack closure, click the + button in the toolbar to open the Library, then drag a Vertical Stack into the new line:

As you expect by now, code and preview update:

Note: The minimap doesn’t appear in my screenshots because I hid it: Editor ▸ Hide Minimap.

Now finish your outline so it looks like this:

VStack {
  HStack {
    Text("Target Color Block")
    Text("Guess Color Block")
  }

  Text("Hit me button")

  VStack {
    Text("Red slider")
    Text("Green slider")
    Text("Blue slider")
  }
}

The new VStack will contain three sliders, and there will be a button between the color blocks and the sliders.

Note: At the time of writing this article, Xcode 11 was beta software, and it had difficulties figuring out what I was doing wrong. It had a few unhelpful error messages, including Unable to infer complex closure return type; add explicit type to disambiguate, ‘(LocalizedStringKey) -> Text’ is not convertible to ‘(LocalizedStringKey, String?, Bundle?, StaticString?) -> Text’ and Function declares an opaque return type, but has no return statements in its body from which to infer an underlying type, which basically meant “huh??”. And these messages seldom appeared near code that I had just added. If you see messages that don’t seem helpful, or point at code that was perfectly fine before, try commenting out what you just added. Also check your spelling and ensure that your braces and parentheses match. Finally, restarting Xcode is always a good idea, both during and after the beta! ;]
  • 1
  • 2
  • 3
Mark complete

Sign up/Sign in

With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!

Create account

Already a member of Kodeco? Sign in

Audrey Tam
Getting Started, User Interface, iOS & Swift Tutorials

4.6 (121) · 1 Review

Save for later

Sign up/Sign in

With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!

Create account

Already a member of Kodeco? Sign in

This content was released on Jun 10 2019. The official support period is 6-months from this date.

In this SwiftUI tutorial, you’ll learn how to layout the UI by declaring and modifying views, and how to use state variables to update your UI. You’ll use Xcode’s new preview and live preview, and experience the joy of code and WYSIWYG layout that stay in sync.

Comments
Download materials

Sign up/Sign in

With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!

Create account

Already a member of Kodeco? Sign in

Share

Share this

Twitter

Share

Facebook

Share

Email

Share

Contributors

Audrey Tam

Author

Adriana Kutenko

Illustrator

Richard Critz

Team Lead

Over 300 content creators. Join our team.

All videos. All books.
One low price.

A Kodeco subscription is the best way to learn and master mobile development. Learn iOS, Swift, Android, Kotlin, Flutter and Dart development and unlock our massive catalog of 50+ books and 4,000+ videos.

Learn more

Places

  • iOS & Swift
  • Android & Kotlin
  • Flutter & Dart
  • Server-side Swift
  • Game Tech
  • Professional Growth
  • Community
  • Library

Company

  • About
  • Jobs
  • Terms of Service
  • Privacy Policy
  • Advertise

Support

  • Help
  • FAQ
  • Contact Us

Community

  • Community Page
  • Discord
  • Podcast
  • Forums
  • Newsletter
  • Free Books for Meetups

All videos. All books.
One low price.

Learn iOS, Swift, Android, Kotlin, Flutter and Dart development and unlock our massive catalogue of 50+ books and 4,000+ videos.

Learn more

The largest and most up-to-date collection of courses and books on iOS, Swift, Android, Kotlin, Flutter, Dart, Server-Side Swift, Unity, and more!

© 2025 Kodeco Inc