iOS — Custom UIPageControl with UIPageViewController

UIPageControl usually works with an UIPageViewController or a paginating UIScrollView. For example, Instagram. Can we customise it as elegant as possible? 😉

Myrick Chow
ITNEXT

--

A UIPageControl with custom tint colour and image sources

UIPageControl is a control that displays a horizontal series of dots, each of which corresponds to a page in the app’s document or other data-model entity. It usually works with a UIPageViewController or a paginating UIScrollView. The default UIPageControl only shows page indicator as white circles with different opacities.

Default UIPageControl layout

iOS framework provides different parameters for us to customise the UIPageControl. They include indicator tint colour and images for current and other pages.

The UIPageControl within the iOS Instagram app

We need to add a custom protocol to connect an UIPageControl with an UIPageViewController. It is a little tricky and I will share the step-by-step instructions here!

Prerequisite

The basic implementation of UIPageViewController

The implementation of a basic UIPageViewController will not be covered in this article due to the length of this story. You are welcome to read my article that is about UIPageViewController first to get a basic idea about the workflow.

Step-By-Step Tutorial

Step 1) Adding a UIPageControl widget to your UIViewController and connect to an IBOutlet

Adding a UIPageControl widget to user interface

Step 2) Set custom indicator images

Two sets of icon for page indicators

We can add two sets of images for indicator image — One for the current page and one for the other pages.

UI after setting the image sources of indicators

Tips: Make sure the icon images are having a transparent background since a tint color will be applied to those opaque pixels.

Cat face and background are both transparent; The outline is opaque and is affected by tint colour

Step 3) Apply tint colours to indicator images

UI after applying tint colours

Step 4) Passing events from UIPageViewController to UIPageControl

UIPageControl cannot respond to the UIPageViewController events

At this moment, the UIPageControl cannot react to the change of page in the UIPageViewController. As you can see in the above gif, the black cat icon is still stuck at the first-page indicator even the UIPageViewController has already changed to another page.

We need to link them up with a custom protocol for passing events from the UIPageViewController to the UIPageControl.

There are two functions in the CustomPageViewControllerDelegate:

  1. numberOfPage : To notify the DemoViewController that the number of UIViewController (page) shown at the UIPageViewController has been updated, and therefore UIPageControl should be updated accordingly.

Make sure the customDelegate is marked as weak to prevent an Automatic Reference Counting (ARC) issue, i.e. the MainViewController instance and CustomPageViewController instance both store a reference of the other and instances cannot be released from memory.

2. pageChangedTo: To notify the DemoViewController that the visible UIViewController (page) is changed to another one. The currentPage property of UIPageControl should be updated.

Step 5) Implementing CustomPageViewControllerDelegate at DemoViewController

The first thing we need to do is getting the CustomPageViewController instance through the prepareForSegue callback and set the customDelegate at the same time.

After that, we need to update the numberOfPages and currentPage property of the UIPageControl instance.

UIPageControl can now react to the UIPageViewController events

Step 6) Fix the current page indicator images

As you can see in the above gif, you can see that the current page indicator is highlighted correctly but not the image source. Therefore, we need to call the setIndicatorImage again once the page is changed:

Make sure you reset the tint color of the page indicator at the same time to prevent UI. Moreover, tint color MUST be set before setting the indicator image source.
Reference: iOS 14 UIPageControl unselected page are treated as currentPage — Stack Overflow

The tint colour and image source of each indicator are updated according to the updated page index in UIPageViewController

Step 7) Handle the click and drag action on UIPageControl

Apple has updated UIPageControl since iOS 14. It can now:

  1. Be clickable and switches the current page depending on whether the click is at the left or right half of its frame.
UIPageControl is clickable and the current indicator is changed accordingly

App can disable the click feature by setting the isUserInteractionEnabled property of UIPageControl to false

2. Be long-pressed and show a prominent pop up for users to change pages by swiping on its frame.

A prominent popup is shown after a long press; User can update the selected page by dragging on it

App can disable the prominent pop up feature by setting the backgroundStyle of UIPageControl to minimal.

Therefore, we need to add a ValueChanged connection for the UIPageControl and notify back the UIPageViewController that the user wants to change the currently visible page.

Adding a ValueChanged connection between UIPageControl and UIViewController

Finally, we can then create a function at the CustomPageViewController to update the visible page accordingly.

Yeah!!! We have completed the implementation of a custom UIPageControl !

The final result of a perfect UIPageControl

Summary

UIPageControl is a lovely widget for showing the page information of a UIPageViewController or a paginating UIScrollView. Linking them together requires:

  1. A custom protocol to pass the number of pages and the index of the current page from the UIPageViewController to UIPageControl
  2. A ValueChanged connection to a UIPageControl to notify the UIPageViewController that users want to update the currently visible page

If the prominent popup of UIPageControl does not fit your UI/UX requirement, developers can manually disable it.

Thank you for reading this article. Hope you find it interesting and useful!
You are welcome to follow me and contact me through the following channels:

  1. Twitter@myrick_chow
  2. YouTube@myrickchow
  3. LinkedIn@Myrick Chow

--

--

Writer for

Mobile Lead @REAL Messenger Inc. https://real.co Focus on Android & iOS Native programming.