Jacob’s Tech Tavern

Jacob’s Tech Tavern

Secret SwiftUI: A practical use for _VariadicView

I finally found a use case for this private API

Jacob Bartlett's avatar
Jacob Bartlett
Feb 10, 2025

Inspiration struck. I finally realised a practical use case for _VariadicView: a reusable ChatList component that automatically applies scroll inversion on the contents.


Subscribe to Jacob’s Tech Tavern for free to get ludicrously in-depth articles on iOS, Swift, tech, & indie projects in your inbox every week.

I’m kind of late to the party on this, frankly.

_VariadicView helps us create custom VStacks. Our own flexible tab bars. Bespoke pickers and lists. I started writing this article in March 2024, but was stumped trying to find a non-contrived example—one that would actually be useful in production.

While mulling it over on a mental background thread, this article faded into a dusty backlog alongside aborted magnum opi such as Through The Ages: Apple Concurrency APIs and Dumb Ways To Maximise Your App Binary Size.

Recently, that all changed.

At midnight, I was doing what we all do once our wives fall asleep: reading Vincent Pradeilles. Specifically, his article on building inverted scroll for messaging apps.

Inspiration struck. I finally realised a practical use case for _VariadicView: a reusable ChatList component that automatically applies scroll inversion on the contents.

Today, much like our scrolling, let’s work backwards.

We’ll implement a scroll inversion, and experience the pain point together as our UI grows more complicated. Only then will I introduce _VariadicView, take you under the covers to explain how it all works, then demonstrate how you can use _VariadicView to address this specific pain point in your own apps.

Building an Inverted Scroll

Inverted chat scroll is the cornerstone of messaging app UX. It’s just a scroll view that starts at the bottom (with the newest messages), so the user scrolls up to see older content.

This differs from the standard scrolling feed UX, where you start at the top of the screen and scroll down for more content.

The trick to implementing this is deceptively simple: you flip the scroll view so it’s upside down. This can be done with 2 lines of SwiftUI modifiers:

.rotationEffect(.radians(Double.pi))
.scaleEffect(x: -1, y: 1, anchor: .center)

Applied to a List view, this gives us the “start at the bottom and scroll up” effect we want, however the chat message content is also inverted!

To fix this, we have to apply the same vertical inversion individually to all the pieces of content. This leaves your view looking a little like this:

struct ChatList: View {
    var body: some View {
        List {
            ForEach(message) { 
                MessageView(message: $0)
                    .inverted()
            }
        }
        .inverted()
    }
}

This does the job, but becomes unwieldy and error-prone as you bring your chat app up to parity with iMessage.

As more types of view are implemented like messages, date headers, and text fields, this gets messy fast.

List {
    TextField() 
        .inverted() 

    TextEntrySeparator() 
        .inverted()

    ForEach(message) {
        if message.isDateHeader { 
            MessageDateHeader()
                .inverted()
        }
           
        MessageView(message: $0)
            .inverted()
    }
}
.inverted()

Enter: _VariadicView.

WTF is a _VariadicView?

_VariadicView is a private-ish SwiftUI API, and the underlying implementation detail for many of the container views you use every day.

It sounds pretty obscure, however its naming is actually pretty straightforward: it’s a view that can be passed any number of views, hence variadic.

_VariadicView lets you do one thing well:

  • Create reusable container components

  • …that can handle multiple types of child view passed in

  • …to which you can apply similar sets of modifiers.

Despite being an underscored “private” API, it’s safe to use in production—many @frozen SwiftUI APIs explicitly conform to the protocol. You won’t have to worry about app review when using it—the API is already emitted into your code implicitly whenever you use a SwiftUI container view like HStack.

How to use _VariadicView

We want to set up a simple container for all our chat content that handles the inversion automatically. We want to implement this once, then apply the inverted scrolling for free anytime we like.

Subscribe for free to continue reading

Enter your email and get every post from Jacob’s Tech Tavern.
Already have an account? Sign in
© 2026 Jacob Bartlett · Privacy ∙ Terms ∙ Collection notice
Start your SubstackGet the app
Substack is the home for writing, podcasting, and media founders.