How to Create Onboarding Screens in Your iOS App
By: Can Balkaya
Tags: iOS, Xcode, Mobile, Programming, Swift

How to Create Onboarding Screens in Your iOS App

Photo by Bagus Hernawan on Unsplash

Onboarding screens are important to help new users fully understand the application and have a smooth user experience. If you’re creating an indie app, you should think about onboarding screens.

Although I would like to discuss the design of onboarding screens, I’ll leave that for another article. Here, I’m going to explain how onboarding screens are coded.

Onboarding screen examples from Apple’s Health app

We will code onboarding screens entirely with the UIKit framework. Please create a new Xcode project accordingly.

Speaking of what we will do in general: We’ll split our application in two according to a Bool value that we saved with UserDefaults. The first part of the application will be the main interface of the application. The second part of the application is the section where onboarding screens are located.

Now it’s time to create a new storyboard file. For this, let’s create a new storyboard file, “Onboarding.”

We’ll use the UIPageViewController element to keep the onboarding pages together.

Apple Documentation Overview for UIPageViewController Page view controller–navigation can be controlled programmatically by your app or directly by the user using gestures. When navigating from page to page, the page view controller uses the transition that you specify to animate the change.

Create a UIPageViewController element by dragging it using the object library.

This UIPageViewController must be the initial view controller — because it will manage other view Controllers. That’s why we toggle “Is Initial View Controller” to on.

You can change “Transition Style” to “Scroll” if you want the animation that occurs as the view controllers inside the UIPageViewController change to be a normal scroll animation.

Create a UIViewController element with the object library to create the first onboarding screen.

Put a UIButton and a UILabel element inside this UIViewController element. (It may be easier to use auto layout if you position the elements the way I do.)

Copy and paste this UIViewController element twice and change the text of the UILabel elements according to their order.

Create a file named “MainPageViewController” to bind UIPageViewController element to the code.

Likewise, let’s create UIViewController files one by one to define UIViewController elements.

Let’s connect these defined files with storyboard elements. I first connected the UIPageViewController element.

Likewise, we connect UIViewController elements as follows. I think you can do the rest yourself.

Create a “Storyboard Reference” element to return to the main screen after the third screen.

The Storyboard Reference element is used to link storyboard files. That’s why we choose the storyboard of our Storyboard Reference element as “Main”.

When you click the button on the third screen, create a segue to go to the “Main” storyboard.

Now it’s time for the Main storyboard file. First, go to “Main.storyboard”. When we first created the Xcode project, there is a UIViewController file named ViewController.swift. This file is linked to the UIViewController in the “Main.storyboard” file. Let’s delete every link related to this file and even “ViewController.swift” file.

Create a new Cocoa file named “ConciergeViewController” for our UIViewController element and link this file with our storyboard element.

This UIViewController element is for us to separate screens from each other. It serves to bring different UI elements to us according to the value of the isFirstLaunch property. Two separate UIViewController elements are needed to do this.

We already have the first view controller(s): Onboarding.storyboard!

We need to define an identifier for our segue in order to take action. So let’s write “toOnboarding” as an identifier.

For the second UIViewController we need to create a new UIViewController with object library. In the second one, we need the segue identifier to take action. So let’s write “toMain” as an identifier.

Now we can move on to coding. Let’s first define our class where we will define our UserDefault element. To do that, create a new Swift file that calls LandscapeManager .

Then define LandscapeManager class. isFirstLaunch element will allow us to record whether the application was opened for the first time.

class LandscapeManager {

static let shared = LandscapeManager()

var isFirstLaunch: Bool {

get {

!UserDefaults.standard.bool(forKey: #function)

} set {

UserDefaults.standard.setValue(newValue, forKey: #function)

}

}

}

Second, we need to define a storyboard extension because to be able to define and use our storyboard files more easily.

Write the following codes to take action according to the value of the isFirstLaunch property in ConciergeViewController element:

override func viewDidAppear(_ animated: Bool) {

if LandscapeManager.shared.isFirstLaunch {

performSegue(withIdentifier: "toOnboarding", sender: nil)

LandscapeManager.shared.isFirstLaunch = true

} else {

performSegue(withIdentifier: "toMain", sender: nil)

}

}

Let’s create a UIStoryboard extesion to define storyboard files.

extension UIStoryboard {

static let onboarding = UIStoryboard(name: "Onboarding", bundle: nil)

static let main = UIStoryboard(name: "Main", bundle: nil)

}

Define the view controller elements that we will use inside the MainPageViewController element in an array:

// MARK: - UI Elements

private var viewControllerList: [UIViewController] = {

let storyboard = UIStoryboard.onboarding

let firstVC = storyboard.instantiateViewController(withIdentifier: "FirstStepVC")

let secondVC = storyboard.instantiateViewController(withIdentifier: "SecondStepVC")

let thirdVC = storyboard.instantiateViewController(withIdentifier: "ThirdStepVC") return [firstVC, secondVC, thirdVC]

}()

Then create a feature called currentIndex to know which view controller we are in:

// MARK: - Properties

private var currentIndex = 0

Write the following codes to set the first element of the array, when the viewDidLoad function runs:

// MARK: - Life Cycle

override func viewDidLoad() {

super.viewDidLoad() self.setViewControllers([viewControllerList[0]], direction: .forward, animated: false, completion: nil)

}

Define this function to go to the new page when you click the buttons in the view controllers:

// MARK: - Functions

func pushNext() {

if currentIndex + 1 < viewControllerList.count {

self.setViewControllers([self.viewControllerList[self.currentIndex + 1]], direction: .forward, animated: true, completion: nil)

currentIndex += 1

}

}

We are now done with MainPageViewController . Now all you have to do is write the codes that will run when the buttons in the view controllers are clicked. For that, let’s go to FirstStepViewController .

Define the button of this element as an IBAction function named actionButtonTapped and call the pushNext function inside. This way, when we click the button, we will switch from the first page to the second page:

// MARK: - Actions

@IBAction func actionButtonTapped(_ sender: UIButton) {

if let pageController = parent as? MainPageViewController {

pageController.pushNext()

}

}

Do the exact same of this function in SecondStepViewController but we won’t do this in the third view controller because there is no screen after the third view controller.

We have made our onboarding pages. From now, the only thing you can do is further complicate these pages!