SwiftUI: Multiple Buttons in a Single List Row

In SwiftUI, we love Lists. We love Lists so much because we simply must love Lists because SwiftUI loves Lists and, really, if you've spent any time in SwiftUI you know you're better off just learning to love what it loves.

So, sometimes we put a lot of stuff in a List. You know, really load it up. Maybe we throw in some of our custom views from elsewhere. And this is the part where I usually get caught up and have to re-realize the same thing again. I'll be tapping or clicking around while testing and notice that one button is triggering the action of another. Buttons within my list are all of a sudden unreliable and fire seemingly random bits of functionality.

That is because a list row itself functions as a tap target, so each button within in it does not intercept its own taps. So, the row instead funnels all those taps to one of the Buttons, seemingly at random (or maybe there's an order to it. Don't @ me, I don't really care.) Luckily the workaround is simple: Just set a button style. Any style, just as long as it's not DefaultButtonStyle.

Here's an example where we have three Buttons in the same List row. Each Button sets a different value to a @State variable which defines the color of elements within another of the List's rows.

import SwiftUI

struct ContentView: View {
    @State private var brainsColor = Color.primary
    
    var body: some View {
        List {
            Section {
                VStack {
                    Image(systemName: "brain.fill")
                        .resizable()
                        .scaledToFit()
                        .frame(maxWidth: .infinity, maxHeight: 100, alignment: .center)
                    Text("BRAINS!")
                        .tracking(2)
                        .font(.custom("Silkscreen-Regular", size: 44))
                }
                .foregroundStyle(brainsColor)
            }
            
            Section("Brain Color") {
                HStack(spacing: 44) {
                    Button {
                        brainsColor = .yellow
                    } label: {
                        Circle()
                            .foregroundStyle(.yellow)
                            .frame(width: 44)
                    }
                    
                    Button {
                        brainsColor = .indigo
                    } label: {
                        Circle()
                            .foregroundStyle(.indigo)
                            .frame(width: 44)
                    }
                    
                    Button {
                        brainsColor = .mint
                    } label: {
                        Circle()
                            .foregroundStyle(.mint)
                            .frame(width: 44)
                    }
                }
                .frame(maxWidth: .infinity, alignment: .center)
            }
        }   
    }
}
An animated gif showing the user interface defines above. There is an SF Symbol for a brain and the text "BRAINS!". There are three buttons to toggle the color of the symbol and text, but as they are clicked only one of the buttons' colors gets applied now matter which is clicked.
Please! My buttons! They're very sick!

As implemented, only one color gets set (the last one) no matter which button you click. However, simply adding an explicit button style to each one allows them to function as expected.

Button {
    brainsColor = .indigo
} label: {
    Circle()
        .foregroundStyle(.indigo)
        .frame(width: 44)
}
.buttonStyle(PlainButtonStyle()) // OK, List, does this make you happy?!?
The same interface from before: Three buttons which toggle the color of a brain image and some text. This time the buttons work!
That's satisfying.

Weird!

Fake Album Covers

My initial submission of In Rotation included screenshots featuring album covers from some favorite artists of mine.

App Store screenshots for the app In Rotation. Album covers from David Bazan, Madeline, Kenney, Wheat, and Protomartyr are shown.
If you've yet to listen to Madeline Kenney I pity you.

This, of course, triggered a rejection. I needed explicit, verifiable permission from rights holders. I was not surprised but I'd been hopeful, as I'd found various other apps in my category use album covers from artists as big as Beyoncé in their App Store screenshots. (And like, come on, I know that single-developer app didn't wrangle written permission from Bey's team for their niche Apple Music utility's App Store screenshots.)

Naturally, then, I settled down with a can or four of costly IPA, an image generation AI, and my best friend Pixelmator Pro and put together some fake album covers which I hoped would still allow me to show off my interface a good light. Weirdly this still triggered a rejection, and for the same stated reasoning! (I eventually ended up publishing everything under a CC0 public domain dedication license to get around this. So, hey, feel free to have your way with these jpegs!)

I present a selection of them to you here now, because I'm more proud of them than I should be and because what's more funny than explaining jokes?

An album cover featuring an ethereal figure wrapped in silk with their face obscured. The text "M O O F" is displayed.
M O O F by Claruus

I like to think of Claruus as an early-90s New Age group, the kind you've never heard of but then you find out they won eight Grammys, sold 15 millions records, and still sell out Red Rocks every summer.

This, of course, is a reference to our favorite dogcow. For those uninitiated, I refer you to the great Clarus historian Stephen Hackett.

An album cover featuring a digitally manipulated statue's head and the text "Courage"
Courage by Headphone Jackson

And who could forget the seminal post-rock opus Courage by Headphone Jackson? I saw them open for Mission of Burma once and my ears are still ringing.

This is a reference to our favorite Apple Fellow and his onstage remarks about the reasoning for removing the headphone jack.

this doesnt exist by Nil/Optional

Your parents had this 70s prog rock classic in their collection when you were a kid but you didn't really get it until you got older and discovered drugs.