Docs
Glass

Glass Segments

A segmented control whose glass indicator moves like liquid, stretching across and gathering in, and follows a scrub.

$npx swiftpieces add GlassSegments
Try it in the Playground Use it on a real screen, take it apart, remix it, and copy the SwiftUI. No account needed.
Free · MIT + Commons ClauseiOS 17.0+Liquid Glasssegmentedpickerglassdraghaptics
Type
GlassSegments
Files
GlassSegments.swift
Depends on
Nothing (Apple frameworks only)
Version
2.3.1
In a full screen · SwiftPieces ProLessonsA language-learning home with a streak, today's goals as color blocks and a floating tab bar whose lens follows your finger.

Visual tuning for GlassSegments. standard is a neutral glass track with a signal-tinted glass indicator melted into it, the house ink on the red; set indicatorTint for another tint.

Notes

  • Liquid glass: the track and the indicator are glass shapes in one liquid group (GlassEffectContainer on iOS 26). The track is neutral glass; the indicator is signal-tinted glass resting inside it, joined to it, so the two melt into one surface and the red reads as a lens of colour moving through the glass. The selected label sits on the red in the house ink, which reads on signal, sage and butter alike.
  • The indicator moves edge by edge. On a tap or an external change of selection, the edge facing the new segment leads on a quick spring and lands crisply while the far edge follows on a slightly slower one, so the indicator reaches across (about one and a third segments wide on a move to the neighbour) and gathers in to one segment with a little liquid give: the far edge passes its mark by about 3% of its travel and settles back. The leading edge never overshoots, so the indicator never pokes past the track at either end. Longer jumps stretch further (about two segments wide on a jump of three) and still land in under 0.4s.
  • A touch that lands on the indicator grabs it: it lifts (scale 1.04, deeper shadow) on a spring with no bounce and follows the finger directly, with no catch-up. Its leading edge reaches a little ahead with speed and relaxes when the finger rests. A touch anywhere else is a plain tap on that segment.
  • The indicator can be grabbed on the segment it is headed for while it is still moving there. It finishes that move under the finger instead of jumping to it, and the finger's own movement still applies directly.
  • Past either end, the edge at the wall gives no more than the 3pt track inset while the far edge follows against rubber-band resistance, so the indicator flattens against the end instead of leaving the track. The lift grows toward the wall there, so the lifted indicator stays inside the track too. The selection stays clamped.
  • Release commits to the segment the flick would land on (predictedEndLocation), and both edges leave at the finger's speed into the same edge-by-edge hand-off. The lift comes down on the release spring as the indicator lands. Let go flattened against an end, it springs back to full width without the push.
  • One .selection haptic fires each time the indicator's center crosses into a new segment, once on tap, and once on release only if it lands somewhere new. Changes made through the binding are silent.
  • The binding changes on a short spring with no overshoot, so views that read the selection can animate with it, and a chart or a total switched by it never swings past its new value. A drag that a parent scroll view cancels puts the indicator back in its segment.
  • Reduce Motion removes the stretch, the reach, the flattening and the lift scale (the shadow still lifts): both edges move together on a short spring with no overshoot. Reduce Transparency draws the track and the indicator as opaque fills, the indicator still in its tint. Before iOS 26 both are frosted and simply don't merge.
  • Segments share the width equally; the control fills its container, so constrain it with .frame(width:) when you want it compact.
  • Labels are drawn twice: once in Style.ink, and once in Style.selectedInk masked to the indicator's live shape, so the color hands over exactly under the indicator edge while it moves, stretches or flattens. All type is semibold.
  • indicatorTint sets the indicator's glass tint (nil is the house signal red; .clear leaves it neutral glass), and GlassSegmentsStyle.block(_:) makes one in another tint with dark ink.
  • The example floats the control over a few color blocks, since glass over a flat page reads as grey.
  • Style (GlassSegments.Style, alias of GlassSegmentsStyle): ink, selectedInk, indicatorTint, font, disabledOpacity; track and indicatorSurface are kept for existing code but no longer used, since both shapes are glass. .disabled(true) fades the control and ignores touches. The row height scales with Dynamic Type (capped at 1.5x).
  • For a floating tab bar whose lens follows the finger, see the Pro Lessons screen (lens-tab-bar).

Usage

GlassSegmentsExample()
    .preferredColorScheme(.light)

Install

Pick one. Run it from the folder that contains your .xcodeproj and the files land inside your app.

Terminal

$npx swiftpieces add GlassSegments

Or ask your coding agent · Claude Code, Cursor or Xcode, once the MCP server is connected

>Add the SwiftPieces "Glass Segments" piece to my app

Or copy the source above into your app.

New to SwiftUI?If you know React, CSS or Tailwind, SwiftUI is easier to pick up than it looks.Try real app patterns first

Building a whole app? See SwiftPieces Pro →

All liquid glass →

Build it yourself: Liquid Glass guide

On this page

SwiftPiecesPro

Build the whole app with one library.

Production-ready screens, whole flows, complete app templates, a Build Kit your agent follows and Pro remixing.

54 screens · 46 patterns · 48 flows · 12 templates · 31 Build Kit skills

Explore Pro