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? 😉
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.
iOS framework provides different parameters for us to customise the UIPageControl
. They include indicator tint colour and images for current and other pages.
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 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
Step 2) Set custom indicator images
We can add two sets of images for indicator image — One for the current page and one for the other pages.
Tips: Make sure the icon images are having a transparent background since a tint color will be applied to those opaque pixels.
Step 3) Apply tint colours to indicator images
Step 4) Passing events from UIPageViewController
to UIPageControl
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
:
numberOfPage
: To notify theDemoViewController
that the number ofUIViewController
(page) shown at theUIPageViewController
has been updated, and thereforeUIPageControl
should be updated accordingly.
Make sure the
customDelegate
is marked asweak
to prevent an Automatic Reference Counting (ARC) issue, i.e. theMainViewController
instance andCustomPageViewController
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.
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
Step 7) Handle the click and drag action on UIPageControl
Apple has updated UIPageControl
since iOS 14. It can now:
- Be clickable and switches the current page depending on whether the click is at the left or right half of its frame.
App can disable the click feature by setting the
isUserInteractionEnabled
property ofUIPageControl
tofalse
2. Be long-pressed and show a prominent pop up for users to change pages by swiping on its frame.
App can disable the prominent pop up feature by setting the
backgroundStyle
ofUIPageControl
tominimal
.
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.
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
!
Summary
UIPageControl
is a lovely widget for showing the page information of a UIPageViewController
or a paginating UIScrollView
. Linking them together requires:
- A custom protocol to pass the number of pages and the index of the current page from the
UIPageViewController
toUIPageControl
- A
ValueChanged
connection to aUIPageControl
to notify theUIPageViewController
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.
Read More — Resources & References
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: