Custom Paging UI in SwiftUI

Create animated index views with the new PageTabViewStyle

Alexandru Turcanu
Aug 3 · 3 min read
Image for post
Image for post
Photo by Tyler Lastovich on Unsplash.

SwiftUI 2 introduced a new TabView style called PageTabViewStyle that enables developers to easily create horizontal Pagers (aka Paging) with dots at the bottom to show users where they are. This is the equivalent of UIPageViewController from UIKit.

Today, we will cover how to use the new style for TabView and how to create a custom IndexView component.

Image for post
Image for post
Collection of animations

Getting Started

Using the new API is as simple as setting the new PageTabViewStyle:

Here, I have an array of colors — with each color being a page — and I am also tagging every Color view with its desired index. The TabView initializer has a selection binding that represents the current page.

Image for post
Image for post

A couple of things to keep in mind:

  1. The paging dots are white and translucent. Therefore, if your background is also white, you won’t see them (tested on iOS/Xcode Beta 3).
  2. The contents of the TabView cannot be drawn over the safe area insets (Tested on iOS/Xcode Beta 3).

Creating a Custom IndexView

Now that we have the basics covered, we can quickly create any custom component to represent the current page and update it accordingly with our currentIndex state property.

We are going to take a stab at making a more dynamic version of the system dots. This index component will present at most three dots and animate the insertion/removal as you swipe through the pages.

Image for post
Image for post

That’s quite a bit of code, so let’s go through it step by step:

1. ForEach and shouldShowIndex() — Display only three dots or less (for the current page and its adjacent pages).

2. .fill() and .scale() — Apply different styling to showcase which Circle is focused.

3. .transition() — Animate the insertion and removal of each Circle with opacity and scale.

4. .id(index) — Create unique Circle instances for each index.

Final Step

Now we just need to update ContentView to make use of the new Fancy3DotsIndexView:

  1. Add an implicit animation for every change that happens to the currentIndex binding.
  2. Overlay the new IndexView component and plug in the necessary properties.


Image for post
Image for post
Final product


Making animations in SwiftUI was already insanely easy, and now with the new TabView style, you can create any kind of index view! Stay tuned for my upcoming articles!

If you are feeling brave enough, I encourage you to try to make your own animations!

Better Programming

Advice for programmers.

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store