Define the scroll edge effect style of a scroll view for Liquid Glass

Define the scroll edge effect style of a scroll view for Liquid Glass

Learn how to change the edge effect of the scrolling view behavior in areas where the scroll view intersects with the safe area.

Starting with the 26 OS, ScrollView has been enriched with scrollEdgeEffectStyle(_:for:), a new method that allows for changing the edge effect of the scrolling view. The effect applied by this modifier is especially noticeable in areas where the scroll view intersects with the safe area.

Use this modifier when your ScrollView content reaches the edge of the view hierarchy and you want to customize how the overscroll looks. It becomes particularly useful when the scroll view is part of a more complex layout, such as embedded in a tab bar, or when content underlaps translucent UI elements like toolbars or floating buttons.

Different Scroll Edge Effects Applied: hard - soft.

Customizing the edge effect allows gaining control over the visual feedback users get while scrolling past the content boundary. It helps align the scroll experience with your app's design language.

Let’s see how to implement it.

struct ContentView: View {

    var colors: [Color] = [.yellow, .mint, Color("Malva")]
    
    var body: some View {
    
        // 1.
        ScrollView {
            // 2.
            VStack(spacing: 0) {
                ForEach(0..<50) { x in
                    ZStack {
                        Rectangle()
                            .fill(colors.randomElement()?.opacity(0.7) ?? .gray)
                            .frame(width: 350, height: 180)
                        Text("\(x+1)")
                            .foregroundStyle(.white)
                            .fontWeight(.heavy)
                    }
                    .padding()
                }
            }
        }
        // 3.
        .scrollEdgeEffectStyle(.soft, for: .all)
    }
}
  1. Create a ScrollView instance.
  2. Add the content to be scrolled.
  3. Call the scrollEdgeEffectStyle(_:for:) modifier on the ScrollView .

The scrollEdgeEffectStyle(_:for:) modifier sets the scroll edge effect style for the specified edges and takes two parameters:

  • ScrollEdgeEffectStyle: a structure that defines the style the scroll view will have in a safe area.
  • Edge.Set: the edge or combination of edges (.top.bottom.horizontal.all) the style will apply to.

The ScrollEdgeEffectStyle type comes with 3 built-in style values:

  1. automatic: set by default, the automatic scroll pocket style.
  2. hard: sharp edge with a visible dividing line, ideal for discrete UI boundaries.
  3. soft: rounded, diffused overscroll, more fluid and immersive.

The effect becomes particularly noticeable when your ScrollView overlaps with a safe area, like behind a tab bar or a floating UI element. To demonstrate this in a real-world scenario, we can integrate the scroll view inside a TabView:

struct TabBarView: View {

    var body: some View {
        TabView {
            Tab("Home", systemImage: "house") {
                ContentView()
            }
            
            Tab("Alerts", systemImage: "bell") {
                ContentView()
            }
            
            TabSection("Categories") {
                Tab("Favorites", systemImage: "heart.fill") {
                    ContentView()
                }
                
                Tab("Suggested", systemImage: "lightbulb") {
                    ContentView()
                }
            }
        }
    }
    
}
0:00
/0:10

As you can see, the way the tab bar and the scroll view overlap varies accordingly to the effect style chosen. And when the tab bar minimizes, such as during a scroll gesture, the edge effect becomes even more pronounced.

0:00
/0:10

You can also chain multiple modifiers to apply different effects on each edge:

NavigationStack {
    ScrollView {
        ...
    }
    .scrollEdgeEffectStyle(.soft, for: .top)
    .scrollEdgeEffectStyle(.hard, for: .bottom)
    .navigationTitle("Scroll View")
}

In this example, a navigation bar and related title overlap at the top with the scroll view, utilizing two distinct styles.

0:00
/0:11

With the new scrollEdgeEffectStyle(_:for:) modifier introduced in OS 26, you now have more control over how your scroll views behave at the edges, especially in layouts where they overlap with safe areas or system UI like tab bars.

This lets you better match the scroll feedback to your app’s layout and design. And because it works per edge, you can get pretty specific with how and where those effects show up. It's a small addition, but one that helps polish the scrolling experience in the places where it matters most.