Better Programming

Advice for programmers.

Follow publication

Mocking iOS 15 Section Headers

How to fake iOS 15's default list section header styles

Zane Carter
Better Programming
Published in
4 min readNov 15, 2021
Photo by Maxim Ilyahov on Unsplash

With the release of iOS 15, you might have noticed that the list header style changes slightly. It now has significantly more padding above and below the section. You can see a comparison below.

iOS 14 List vs. iOS 15 List

If you’re not a fan of this change you can change the headers top padding by changing the sectionHeaderTopPadding property on a UITableView or if you’re like me and moved to SwiftUI, then you can use an appearance modifier like so:

UITableView.appearance().sectionHeaderTopPadding = 0

This is all dandy if you want to use lists in your app. You get an (arguably) nice UI tweak for lists, basically for free. But I came across an interesting problem recently when trying to replicate the new style.

Replicating iOS Section Headers

Why would you want to replicate it you ask? Well while working on my latest project (Flora — check it out here), I needed to use a grid in my app as well. I had a ScrollView with a LazyVGrid inside it with a bunch of cells that needed to be separated out into sections by category.

Without the context of a list, section headers default to a completely different font size & weight. Keeping with the same list content as the first example, you can see the “Fruits” and “Vegetables” headers now default to the same default text as a regular Text view.

I wanted to keep a consistent header style across both List views aswell as any ScrollView or LazyVGrid views. Since the user is already likely familiar with the iOS style headers, I thought it’s best to try and mock the iOS Style of header.

… But There’s a Problem

Easier said than done though, as Apple documentation including both SwiftUI and UIKit List/ UITableView views do not expose any useful information about default padding, fonts, or colours.

According to the Apple docs, the default value for sectionHeaderTopPadding is UITableViewAutomaticDimension. Apple Documentation
This doesn’t help us though because neither the official documentation nor exploring the header file gives us any useful information. It must be determined at run time based on the view's context. There’s also no mention of default font size, font weight or font color for the headers either.

With no official source for the default values, we have to turn to trial and error. First I created a regular old list in SwiftUI, ran it on the simulator, and took a screenshot. Now we have a baseline to compare our own implementation to.

First I started with the distance between the top of the header text and the bottom of the section above, in pixels (see below).

Then I started testing values for padding above the text, taking screenshots as I went, until I got results that were within a few pixels of each other. At that point, I knew I’d found a value that more or less matched Apple's implementation.

The font color is pretty clearly Color.secondary which seemed to match spot on. Then for font size, more trial, and error. The font that seemed to match closest was a size of 13 points and a .regular font weight.

Implementation

Putting this all together, we can create a generic view that mocks Apple's implementation.

Here’s all the values I found from some trial and error

  • The font color: Color.secondary
  • The font size: 13 Points
  • The font weight: .regular
  • Leading padding (Padding from the left side of the list row): 14
  • Top padding: 12
  • Bottom padding: 8

Putting all these values into a nice generic view, we end up with something like this:

You can then use this view in your own ScrollView with something like this:

Section(header: MockedSectionHeader(header: "Fruits")) {
Text("Apple")
Text("Orange")
Text("Pear")
}

You may have to add padding to the sides of the LazyVGrid or ScrollView you are using to match a List side padding but now we’ve pretty much matched the iOS header style as close as we can.

This was useful in my own project so if you have the same issue, hopefully, I’ve saved you some time googling & tinkering.

Thanks for reading.

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

Zane Carter
Zane Carter

Written by Zane Carter

I make apps for the AppStore. Currently working on an app that makes gardening easier. Twitter: @iamzanecarter

Responses (1)

Write a response