Docs
Text

Text Reveal

Reveals a headline by characters, words or lines, then grows a stroke of tinted glass behind the phrases that matter.

$npx swiftpieces add TextReveal
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 Glasstextrevealstaggerentrancehighlightscroll
Type
TextReveal
Files
TextReveal.swift
Depends on
Nothing (Apple frameworks only)
Version
2.2.0
In a full screen · SwiftPieces ProOnboardingFirst run end to end: welcome pages, a permission step and a trial offer, then into the app.

Staggered text reveal that wraps correctly at any width and Dynamic Type size. The stagger is derived from the unit count, so a 3-word title and a 60-character sentence both finish in about duration. Phrases listed in highlights get a stroke of tinted liquid glass that grows in behind them once they land, with the text flipping to the house ink under its edge.

Notes

  • The stagger is computed from the unit count: each unit takes about half a second to land and the rest of duration is spread across the starts, so long sentences do not crawl. The starts are eased rather than even: the first units leave a little closer together and the last ones settle in with a little more room, and the total stays the same. Pass a larger duration for a slower reveal.
  • Words and characters are laid out by a private wrapping Layout, so the text breaks across rows like normal text and characters never split a word. .lines renders each \n-separated line as one wrapping Text. All motion is render-only (offset, blur, scale, a drawn path), so wrapping never shifts during a reveal.
  • Splitting text into Text views loses kerning and ligatures between units; .words keeps them inside each word and is the best default for body-sized type.
  • Every preset arrives on the same calm spring with no visible overshoot, so a word never bobs past its baseline. .rise slides each unit up from behind its own baseline (a mask at the unit's bottom edge); set Style.masksRise = false for a 10pt float instead. .blur resolves from Style.blurRadius and .soften scales up slightly from the baseline as it fades in.
  • highlights takes whole-word phrases. A matched phrase is kept on one row. Once its last unit has nearly landed, a stroke of liquid glass tinted Style.highlight (butter by default) grows in behind it from the leading edge like a highlighter, keeping its round caps the whole way, on one smooth pass of Style.highlightDuration with no overshoot. An ink copy of the phrase in Style.highlightInk (the house ink) is uncovered by the same stroke while the base text gives way under it, so the color flips exactly under its edge. The highlights share one liquid group: two highlighted phrases side by side flow into one stroke. Under Reduce Transparency the glass is a solid block of the tint; before iOS 26 it is frosted.
  • Type is semibold, the house weight, set at the piece's root; size and colour carry the hierarchy.
  • revealOnScroll uses onScrollVisibilityChange on iOS 18; on iOS 17 it reveals on appear. Change trigger to replay: the current text fades out as one piece where it stands, and once it has mostly cleared (after about 0.16 s, added to delay) the new reveal rises in its place. When text changes along with trigger, the old text is what fades; a new text without a new trigger swaps in place with no replay. The layout takes the new text's size at once, since a fading copy takes no space.
  • Reduce Motion keeps the reveal and drops the movement: every unit fades in together with no lift, blur or scale, a highlight then fades in behind its phrase at full length instead of growing across, and a replay fades the old text out, then the new one in.
  • VoiceOver reads the whole string as one element from the start, whatever the reveal is doing.
  • Style (.standard uses the house palette): highlight, highlightInk, masksRise, blurRadius, highlightDuration.
  • For a complete first-run flow with revealed headlines, see the Pro Onboarding screen.

Usage

TextRevealExample()
    .preferredColorScheme(.light)

Parameters

ParameterDescription
textThe string to display. With .lines, split lines with \n.
unit.characters, .words or .lines. Characters never break mid-word.
preset.rise (lift from a baseline mask), .blur (resolve from a soft blur) or .soften (scale and fade).
alignmentRow alignment, like multilineTextAlignment.
durationTarget time for the whole reveal, in seconds.
delayDelay before the first unit starts, useful for sequencing a subhead after a headline.
revealOnScrollWhen true, the reveal waits until the view scrolls into view (iOS 18). Below iOS 18 it reveals on appear.
triggerChange this value to replay the reveal.
highlightsPhrases (one or more whole words, matched case-insensitively, ignoring punctuation) that get a glass highlight after they land. A highlighted phrase never breaks across rows. Ignored with .lines.
styleHighlight tint and ink, rise mask and blur radius. Defaults to the house palette.

Install

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

Terminal

$npx swiftpieces add TextReveal

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

>Add the SwiftPieces "Text Reveal" 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 text →

Build it yourself: SwiftUI animations guide · 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