SwiftUI Onboarding View
Tags: swift, swiftui, ios, beginners
Published: 2021-04-19 12:55:16

This post is intended for `iOS 14.0+` versions as I'm using `PageTabViewStyle` for creating this onboarding view.

## What we will create

![Onboarding](https://media.giphy.com/media/cL4ussBwKGLWGxgQYD/giphy.gif)

## Creating project

1. Open Xcode.
2. Choose an `App` template for your new project.
![New project](https://i.imgur.com/1j6KfOt.png?1)
3. Create project name and make sure that you have selected `SwiftUI` interface and life cycle.
![Project name](https://i.imgur.com/FymsocJ.png)

## Project assets

To follow along you can download project assets from [GitHub](https://github.com/Sangsom/Onboarding-view-weather/tree/main/Project%20Assets).
Or even better find your own images for your onboarding view.

Take downloaded assets and move them into Xcode project `Assets` folder.
![Project assets](https://i.imgur.com/jUDjzsA.png)

## TabView

Now let's implement the `TabView` structure in our `ContentView.swift` file that will be used for this project.

{% gist https://gist.github.com/Sangsom/f4730acac62bdad6d74abc52676b94f2 file=Onboarding_tabView_1.swift %}

1. Create a `State` property wrapper that will track which `Tab` is currently active.
2. Add `TabView` with sample views currently that will be later replaced with onboarding views.
3. Set `.tag` identifiers for each view so `SwiftUI` can differentiate our views. `Tag` values basically can be any type that conforms to `Hashable` protocol. By default these are `String`, `integers`, `floating-point`, and `Boolean` values. In our case we are just using `Int` values.

If we compile and run our app we now have the following:

![TabView](https://i.imgur.com/J75cs9c.png)

And it doesn't do much. We can't use swipe to change the screen and actually in the bottom you can see that there is empty `TabView` appeared that you can tap and views will be changed, but this is not what we want to achieve.

Add to `TabView` following modifier:
`.tabViewStyle(PageTabViewStyle())`

And if you run your app again you will see that the `TabView` is disappeared from the bottom, but now you can use swipe control to switch between views. Looks good but we need one more modifier.
`.indexViewStyle(PageIndexViewStyle(backgroundDisplayMode: .always))`

This modifier adds to the bottom of our view a paging dots that shows visually on which page you currently are.

![TabView Swipe](https://media.giphy.com/media/sEZWTJHvSmfOR1Qj9H/giphy.gif)

{% gist https://gist.github.com/Sangsom/f4730acac62bdad6d74abc52676b94f2 file=Onboarding_tabView_2.swift %}

Basically you have implemented the main part of the onboarding view experience. Now you can create your own `SwiftUI` views add it to `TabView` and don't forget to assign it's `.tag` attribute.

If you want you can follow to read and see my implementation of onboarding view or use this `TabView` structure and create your own.

## Onboarding Views

For the tutorial we will have 3 onboarding views that have the same structure and style, just different images and text. So we will create re-usable `OnboardingView` component to which we will pass `OnboardingData` model that contains view images and text.

Let's start with `OnboardingData` struct.

1. Create new `Swift File`.
2. Call it `OnboardingData.swift`.
3. Create struct.
4. And also for the tutorial lets add all our sample data in our `OnboardingData` struct itself.
5. Additionally we will make this structer  to conform `Hashable`, and `Identifiable` protocol so we can later use in our `ContentView` to iterate through `ForEach`.

Doing so we will be able to easily iterate through `OnboardingData` list and pass data to our onboarding views, and also we will use this four our `SwiftUI preview` debugging.

{% gist https://gist.github.com/Sangsom/f4730acac62bdad6d74abc52676b94f2 file=OnboardingData_sampleData.swift %}

Now when we have created OnboardingData model we can start creating our OnboardingView.

1. Create new `SwiftUI View`.
2. Call it `OnboardingView.swift`.
3. Create an `OnboardingData` property.
4. Pass to our preview data to fix the error and allow to see in our assistant window dummy data so we can see and create `UI`.

{% gist https://gist.github.com/Sangsom/f4730acac62bdad6d74abc52676b94f2 file=OnboardingView_1.swift %}

And then create an `UI`. Nothing fancy here just two `Image` views that are positioned on top of another, two `Text` views, and a `Button`.

{% gist https://gist.github.com/Sangsom/f4730acac62bdad6d74abc52676b94f2 file=OnboardingView_2.swift %}

Looks good but lets add a small animation to make it live.

1. Add `@State` property wrapper for holding animation state.
  
`@State private var isAnimating: Bool = false`

2. Add scale effect modifier to second image.

`.scaleEffect(isAnimating ? 1 : 0.9)`

3. Trigger animation when `View` will appear. So every time when the user will swipe onboarding view we will get a small scale animation. See the finished `OnboardingView.swift` code.

{% gist https://gist.github.com/Sangsom/f4730acac62bdad6d74abc52676b94f2 file=OnboardingView_3.swift %}

And the last thing is update our `ContentView.swift` file so we can see our Onboarding views.

{% gist https://gist.github.com/Sangsom/f4730acac62bdad6d74abc52676b94f2 file=Onboarding_tabView_3.swift %}

And that's all we have created a nice looking onboarding view.

![Onboarding View](https://media.giphy.com/media/cL4ussBwKGLWGxgQYD/giphy.gif)

## Final thoughts

If you wonder why I'm resetting `isAnimating` state property wrapper on view appearing every time as it already is declared as false, then I did this because I received unexpected behaviour that the animation wasn't triggered smoothly every time I swiped the view. So I did this workaround and it works well. If you have any ideas why is that happening, let me know.
And please leave your critique, comments for this post as it's my first post ever made! I would really appreciate that!
> Thank you!

Follow on [Twitter](https://twitter.com/domanovdev).
Link on full project code on [GitHub](https://github.com/Sangsom/Onboarding-view-weather).