How to build a tutorial with Page View Controller
First at all, in your ongoing project or in a new project you have to add a Page View Controller to be the "director" and one View Controller for each page of the tutorial but better... we will add only one View Controller for all pages because the most tutorials have the same elements in all pages, so we can save time and resources and manage dynamically the content...
Next, in the "Identity inspector" you must assign a storyboard ID for the Page View Controller and another one for the View Controller...
Page View Controller | View Controller |
---|---|
![]() |
![]() |
Now, we can put the necessary objects in the view controller, maybe a title, an image and a description (of course with the respective constraints) and we create the view controller file (TutorialContentViewController.swift) and link the corresponding IBOutlets in the code file:
Now, we need to create a simple class (TutorialStep.swift) to manage the data for each page of the tutorial, next you could add the attribute and assign the values from the object to the IBOutlets in viewDidLoad()...
TutorialStep.swift | TutorialContentViewController.swift |
---|---|
![]() |
![]() |
So far so good but we are missing something very important and it is the class for the Page View Controller, this class will control how we go forward or back in the tutorial, so, after you create the TutorialPageViewController.swift you need to link the view with the file:
Creating the file... | Linking... |
---|---|
![]() |
![]() |
In this file, we will create an array of TutorialStep and in the viewDidLoad() we will fill the elements with the information for each page of the tutorial:
Now that we have created the array, what follows is implement in the same file the two methods of the delegate to navigate between the pages (viewControllerAfter and viewControllerBefore)...personally I like implement these methods in an extension:
Sorry, I forgot to mention that I created a third method (getViewController) to reuse some code... what I did in these methods was get the next or previous index depending on the user movement, next I instantiate the view controller and I assign the correct tutorialStep to the this view controller.
But... I have not assigned the delegate and how will I load the first page of the tutorial?... well, this will be in the viewDidLoad() method as follows:
Ok, at this point we want to test the tutorial but, the tutorial is not the initial view controller, so we need to load this from the initial viewController, in this case is the view controller that I use as home: we can do this in the viewDidAppear() method as follows:
Could you see how it works?... something is missing, I can't see how many pages I have, so we can add a Page Control, by default it is white, so you need to change the tint color if you have a white background:
That is all?... almost, we must create the IBOutlet and set the Page control with the current page and the number of pages in the viewDidLoad():
Did you see how it works with the Page control?... now, we need a way to close the tutorial... so we will add a button and we will create a IBOutlet because we will change the button text, if it is the last page, the text will be "Close", on the contrary the text will be "Next":
Now we need to know if we are in the las page to change the text of the button, so we need to add in TutorialContentViewController an attribute to store the total items in the array:
var totalPages: Int!
By the way, we need to change this line:
self.pageControl.numberOfPages = 3
to this:
self.pageControl.numberOfPages = self.totalPages
It is because have no sense to set the total of pages to 3 if we have an attribute with that value and to complete this, it is necessary send that value from getViewController() in TutorialPageViewController as follow:
Next, we can add in the viewDidLoad() of TutorialContentViewController the next lines to set the title:
We're almost done, now we have to create an IBAction to the button:
Finally, at this point when you press the "Close" button, this tutorial appear again and again and you want the tutorial appear only the first time I open the app, right?... We doesn't want to see the tutorial each time we use the app so we can use userDefault to store a state to indicate that the user have seen the tutorial... It would be when the user press the "Close" button:
To complete this functionality, we need to modify the function viewDidAppear() in ViewController (initial controller) to get the value of "tutorialHasBeenSeen" and validate if the user has seen the tutorial:
You can download the code here.
That is all! I hope you have found useful this material. Thanks!