Docs
Lists

Depth Carousel

Paged cards that recede in depth as they leave the centre, over a glass page counter and a track you can scrub.

$npx swiftpieces add DepthCarousel
Free · MIT + Commons ClauseiOS 17.0+Liquid Glasscarouselscrollpagingdepthparallaxcounter
Type
DepthCarousel
Files
DepthCarousel.swift
Depends on
Nothing (Apple frameworks only)
Version
2.2.1
In a full screen · SwiftPieces ProGalleryA trip album that pages with depth, captions on color blocks, and a pinch to peek at the centred photo.

Centered paging carousel with depth recession, per-page parallax phase, and a progress-linked indicator.

Notes

  • Snapping uses .scrollTargetBehavior(.viewAligned) with content margins sized so the aligned page is centered; the first and last pages center too. Fractional progress is read from the page row's position in a coordinate space named on the scroll view itself (the built-in .scrollView space starts inside the content margins), so it lands on whole pages and works on iOS 17 without onScrollGeometryChange.
  • Depth is driven by the same progress: pages shrink by style.recede, fade by style.dim, and their shadow gets lighter and leans back toward the centered page as they leave center. The phase handed to your content is -1...1, for inner parallax; the example drifts a cropped ink disc by phase * 40 inside a solid color card. Under Reduce Motion the phase is 0 and only the dim remains.
  • Hold a neighbor page and it starts forward, about a third of the way to center; tap it and it comes the rest of the way on the snap spring that every tap, scrub and VoiceOver page move uses. A swipe that starts on a neighbor scrolls as usual and cancels the press. The centered page keeps its own gestures.
  • The pages stay your content; the indicator under them is liquid glass. A "01 / 04" counter (current page in rounded semibold, total dimmed, with a short roll and no overshoot as it changes) sits on a glass capsule joined by a liquid neck to the glass track that carries the dots, so the two read as one control, centered under the pages. The current page is a pill of tinted glass (style.indicatorActive) riding inside the track. It is drawn in absolute page coordinates, as a pure function of the scroll position, so it never lags the pages and never jumps when one settles. Between two dots its leading edge reaches the next dot first and its trailing edge follows, so it stretches by up to half the dot spacing and gathers in as the page lands. Past the first or last page it flattens against the end dot as the scroll view rubber-bands, and springs back with it. On iOS 26 this is Liquid Glass; before that frosted Material, and under Reduce Transparency solid fills.
  • While you drag the pages or touch the track, the dots dim and the pill widens, on one press spring. They settle back on the snap spring as soon as you let go of the track, or once dragged pages come to rest, so after a fling they stay active until the pages land. The whole 44pt-tall track is scrubbable: the pill glides onto the finger in about 0.1s while following its movement 1:1, flattening against the ends if you pull past them, while the pages follow on the snap spring, with a selection haptic per page. On release the pill eases back to the page position; touch the track again before it gets there and it is picked up from where it is drawn, without a jump.
  • Style (DepthCarousel.Style, also DepthCarouselStyle): recede, dim, shadowOpacity, indicatorActive, indicatorInactive, showsCounter. With showsCounter off the track stands alone.
  • Reduce Motion: pages don't scale or hand out a phase, and keep their dim. The pill slides rigidly without stretching, stops at the ends and doesn't widen; the dots still dim. A held neighbor shades slightly (darker in light mode, lighter in dark) instead of moving forward. The counter fades instead of rolling, and page moves land on a short spring with no overshoot. Native paging and its fling are unchanged.
  • VoiceOver treats the carousel as one container that reads "Page x of y" and supports swipe up/down to change pages; the indicator is hidden from it.
  • scrollClipDisabled() lets neighbor pages peek past the carousel's own bounds, so give it full width.
  • Want blur-and-tone depth, pinch peek-zoom and a full album screen? That is the Depth Gallery screen in SwiftPieces Pro.

Usage

DepthCarouselExample().preferredColorScheme(.light)

Parameters

ParameterDescription
dataIdentifiable collection of pages.
itemWidthWidth of each page. Pages are centered in the carousel.
spacingGap between pages.
showsIndicatorShow the counter and pill indicator under the carousel, on liquid glass. The pill track is scrubbable.
selectionOptional binding to the centered element's id, for reading the page or moving programmatically.
styleDepth amounts, indicator colors and whether the page counter shows. Defaults to the house palette.
contentBuilds one page from an element and its phase: 0 at center, -1 one page toward the leading edge, 1 toward the trailing edge. Use it for inner parallax, for example .offset(x: phase * 24) on a shape inside a clipped card.

Install

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

Terminal

$npx swiftpieces add DepthCarousel

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

>Add the SwiftPieces "Depth Carousel" 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 lists →

Build it yourself: SwiftUI loading states guide · SwiftUI cards 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