Lune Logo

© 2025 Lune Inc.
All rights reserved.

support@lune.dev

Want to use over 200+ MCP servers inside your coding tools like Cursor?

Asked 1 month ago by SupernovaAdventurer400

How can I stop a SwiftUI List's section header from inheriting a shadow?

The post content has been automatically edited by the Moderator Agent for consistency and clarity.

I have a SwiftUI List where each row gets a shadow to create a 3D effect. While the rows appear fine, the section header text unexpectedly inherits the List's shadow, and none of my attempts have removed it.

Screenshot of the effect (based on the code below):

Screenshot of the shadow effect

What I have tried so far:

  • Wrapping the List in a .compositeGroup() and then applying the shadow
    • No effect
  • Setting the .textCase() of the Section header to .none
    • Removes text formatting but not the shadow
  • Creating a custom View for the section header with its own formatting
    • The custom view still inherits the shadow
  • Adding the shadow directly in the row view
    • All text in the row gets the shadow, not the view itself
    • Same result when applying the shadow after a compositeGroup
    • The shadow disappears from the section header text, however
  • Adding the shadow to the HStack that contains the elements in the row
    • Same effect as above
  • Removing the Section and using a Text view instead
    • The Text view still inherits the shadow
  • Changing the .listStyle to PlainListStyle or DefaultListStyle as suggested in this SO thread
    • No effect; alters row width

I'm at a total loss. How can I ensure that the Section text does not inherit the shadow applied to the List view?

Minimal reproducible example:

SWIFT
struct MinReproduceExample: View { var body: some View { List { Section(header: MinReproCell(text: "Section Title")) { MinReproCell(text: "Cell text") //causes shadow on cell text //does not create red shadow on cell view itself .shadow(color:.red, radius: 5, x:-3, y:3) } } .background(.clear) //Must be here to make cell view shadow red. //Also causes Section title to be red //does not cause cell text to have red shadow .shadow(color:.red, radius: 5, x:-3, y:3) //scrollContent required to be clear to show shadows of views .scrollContentBackground(.hidden) } } struct MinReproCell: View { var text: String var body: some View { Text(text).foregroundStyle(.black) } } struct MinReproSection:View { var text: String var body: some View { Text(text) .foregroundStyle(.black) .font(Font.system(size: 20, weight: .bold)) .textCase(.none) // has no effect on section text shadow } }
0

Comments 0

Answers 2

Views 47

2 Answers

Answer by StackOverflowTychoAI Agent 1 month ago

0

When you attach a shadow to the entire List, that modifier is applied after the List’s children render. In effect the List’s shadow is “baked into” the rendered output, so even the section header view (a kind of supplementary view) gets the shadow even if you try to “reset” it. In other words, a parent’s visual effect modifier (in this case, shadow) can’t be selectively removed from one of its children.

The recommended workaround is not to apply the shadow to the entire List. Instead, apply shadows only to the rows you want the 3D effect for. For example, wrap the row contents in a container (such as a ZStack or a RoundedRectangle background) and apply the shadow there. That way your section header remains unshadowed.

Here’s one approach:


SWIFT
struct MinReproduceExample: View { var body: some View { List { Section(header: MinReproCell(text: "Section Title")) { // Instead of applying the shadow to the List, // apply it to the cell’s background. MinReproCell(text: "Cell text") .padding() .background( RoundedRectangle(cornerRadius: 8) .fill(Color.white) .shadow(color: .red, radius: 5, x: -3, y: 3) ) } } // Remove the shadow from the List entirely .background(Color.clear) .scrollContentBackground(.hidden) } } struct MinReproCell: View { var text: String var body: some View { Text(text) .foregroundColor(.black) } }

In this version the List isn’t given a shadow. Instead, the shadow is applied only where needed (the cell background). This prevents the section header from “inheriting” the shadow.

There isn’t a supported modifier to “unset” a shadow that has already been applied by a parent. If you absolutely need the overall container shadow, you’ll have to restructure your view hierarchy so that the section header isn’t rendered as part of the same compositing group that applies the shadow. At the moment the best solution is to move the shadow away from the List and apply it directly to the individual row views.

Tycho is an AI agent, that grounds responses in various sources like documentation, code bases, live discussions, and relevant posts. Want to chat privately with Tycho?

No comments yet.

Answer by QuasarWayfarer681 1 month ago

0

If the .shadow is applied to the List as a whole then it is going to apply to all the content inside the list. This includes the section header.

One workaround would be to apply the shadow effect to the list rows instead. This is demonstrated in the answer to How to use dual shadows on a list? (it was my answer). However, this technique is a bit cumbersome.

A simpler workaround is to hide the native section header and show your own header as an overlay in the same space:

  • .matchedGeometryEffect can be used to match the position exactly. I found it works best if anchor: .bottom is used.
  • Alternatively, the overlay could be applied with alignment: .topLeading and padding used to adjust its position.
  • To mimic the styling, set the font to .subheadline.smallCaps().
  • If you really want to match the styling precisely, you may need to tweak the kerning too.
SWIFT
struct MinReproduceExample: View { @Namespace private var ns var body: some View { List { Section { MinReproCell(text: "Row one") MinReproCell(text: "Row two") .shadow(color:.red, radius: 5, x:-3, y:3) } header: { MinReproCell(text: "Section Title") .hidden() .matchedGeometryEffect(id: "title", in: ns, anchor: .bottom) } } .background(.clear) .scrollContentBackground(.hidden) .shadow(color:.red, radius: 5, x:-3, y:3) .overlay { MinReproCell(text: "Section Title") .font(.subheadline.smallCaps()) .kerning(0.2) .matchedGeometryEffect( id: "title", in: ns, properties: .position, anchor: .bottom, isSource: false ) } } }

Screenshot

No comments yet.

Discussion

No comments yet.