Presenting Content In Pages Using SwiftUI

Posted in SwiftUI

Updated on August 28th, 2023

⏱ Reading Time: 4 mins

One of the tasks iOS developers often come to perform is to present paged content. That usually happens in on-boarding screens, as well as other parts in apps where users should scroll left or right to see subsequent content. Doing so in SwiftUI is surprisingly easy, especially when comparing to UIKit where things are a bit more tricky.

I have already demonstrated a related how-to in an older post, but not as a standalone topic, rather as the last part of another one. Nevertheless, it’s a programming technique that definitely deserves its own tutorial, so let’s stick just on that to find out how to show content in pages using SwiftUI.

Creating Pages

What usually indicates paged content is the appearance of a series of white dots at the bottom side of the screen, where each dot matches to a page and the selected dot is the current page. These dots are also known as the page index view.

Although that view is usually there so users have a visual feedback about the page they are in and the remaining ones, it’s also possible to make it invisible. This doesn’t change the fact, though, that the presented content is still separated in pages.

If you have not implemented something similar before in SwiftUI, then you’ll probably realize with surprise that the page index view is actually a “disguised” tab view. What makes the difference and changes the default appearance and behavior of the tab view is just a single view modifier.

Let’s take things step by step, so for starters consider the following simple view implementation. It contains a tab view with five items:

The selected page is stored in the following property:

The formattedText(_:backgroundColor:foregroundColor:) content of each tab item is implemented in the following method marked with the @ViewBuilder attribute:

Note: You can read more about creating SwiftUI views in methods using the @ViewBuilder attribute in this older post.

In order to show the above content in pages, the simplest move that we can do is to change the tab view’s style using the tabViewStyle(_:) modifier and provide the page argument:

Notice that the text given to Text views in all tab items is disregarded, and a dot matches to each page.

Showing and hiding the page index view

By default, the page index view is visible so users can easily know how many pages exist to go through, and what page they are currently in. However, there are cases where displaying it is not a desirable behavior of the app.

To make the pages indicator invisible, we use the tabViewStyle(_:) modifier once again. This time, however, page is not a static property, but a static method that accepts the visible state of the indicator as argument. The never argument, for instance, hides the dots permanently:

There are two more values that we can give as arguments; always and automatic. The former forces the pages index view to be always visible, while the latter makes it visible only when there are more than one pages.

Page index view and the white background

A permanent issue of the page index view is that dots are not visible in light background. The following image illustrates that:

The fix comes by applying an additional view modifier to the tab view, called indexViewStyle(_:). To find out how it works, take a look at the last modifier in the following code snippet:

See that the argument of the indexViewStyle(_:) view modifier is a PageIndexViewStyle instance. While initializing it, we specify the desired value for the background. Passing always will give us the next result, making dots visible in the light background:

There are three more values that can be supplied as arguments:

  1. never: The background will never be displayed. That’s equivalent to not applying the indexViewStyle(_:) modifier at all.
  2. automatic: The background will be displayed or not, depending on the operating system the app runs to.
  3. interactive: The background becomes visible only when users interact with the page index view, i.e. touch and scroll in the dots so as to present quickly another page.

Replacing the default dots

It’s possible to replace the white dots of the page index view with custom images when presenting paged content. The only requirement to achieve that is to use Image views in the tab items instead of text.

To demonstrate that, here’s the previous tab view using Image views in tab items. Images are random SF Symbols:

The result is illustrated right next:


Coming to the end, all we can say is that presenting content in pages is an easy task in SwiftUI. It doesn’t introduce an additional learning step, as it’s based on the tab view; a view that if you know how to handle already, then you’re just a couple of view modifiers away from configuring the page index view as you prefer. And most importantly, you have more time to spend on the actual content creation. I hope you enjoyed this post, thanks for reading!

Stay Up To Date

Subscribe to my newsletter and get notifiied instantly when I post something new on

    We respect your privacy. Unsubscribe at any time.