Screen · Health

New

Intervals

Intervals you build on steppers and run full screen in the color of each phase, with the whole workout as a strip you move through.

An interval timer: pick a format (Tabata, EMOM, a pyramid, a ladder or your own), set rounds, work and rest on steppers and watch the workout's rhythm redraw. Start fills the screen with the phase's color: a giant countdown, the move and what comes next, a level that rises through each interval and the rhythm strip along the bottom lighting up as you go, with a three-two-one count, haptics and count-in tones you can switch on. A training session runs in it too, counted move by move and set by set.

SwiftUIiOS 17.0+interval-timer

Get Swift Pieces Pro

$199 once, every piece included. See how installing works · Sign in

01

What's included

SwiftUI source you own, built on Apple frameworks only.

  • Formats you shape on steppers, with the rhythm redrawing as you go
  • A full-screen session in the color of each phase
  • A level that rises through every interval, and the whole workout as a strip
  • A three-two-one count with haptics, and count-in tones you can switch on
  • A pure IntervalClock you can test, driving the whole session

In the Build Kit

Health and Fitness (brief). Your agent builds around this screen in the same design.

Used in

Fitness App (template)

02

Implementation notes

How it behaves, what it handles, and the decisions behind it.

The builder opens on a row of formats: Tabata, EMOM, a pyramid, a ladder and your own, each chip carrying a tiny strip of its rhythm in the format's block, and the chosen one turning into that block. Under it the workout's total sits as a giant light numeral with its rhythm in words, "8 rounds · 20 s work · 10 s rest", and then the workout itself as a large rhythm strip: work as tall bars in the block, rest as short pale ones, every bar as wide as it is long and 2pt from the next. Three stepper tiles set rounds, work and rest; hold minus or plus and it repeats with a tick per step while the strip redraws with a spring and the total rolls. Start fills the screen with the phase's color. A lighter level rises from the bottom through each interval, the phase, a giant countdown, the move and what comes next sit left aligned in the middle, and the session runs along the bottom as the same strip, the bars behind you in solid ink and the current one filling. Work, rest and "Get ready" each take their own block, the last three seconds pulse the numeral with a light haptic each, and every change lands a firmer one.

Notes

  • IntervalTimer(plans:) is the builder with the session built in: Start presents IntervalSession full screen. Pass onStart to present it yourself, onSave to keep edits (Save appears beside Start once a format is changed), onFinish for the summary and opened to select a format on appear.
  • A format is an IntervalPlan: work durations (one value for most formats, a run for a pyramid or a ladder), rest, rounds, a "Get ready" count, a cool-down and move names. IntervalPlan.formats ships Tabata, EMOM, Pyramid, Ladder and Custom, and IntervalPlan.steps(id:name:steps:) builds one from explicit steps, such as a training session's sets.
  • IntervalClock(plan:) is pure: state(at:) returns the phase, the round, the time left in the phase and the overall progress for any second, so the session is easy to test. IntervalRun holds elapsed time and pause; give one run to IntervalSession(run:) and to a compact player and both follow the same clock.
  • RhythmStrip draws any workout from RhythmBeats (IntervalPlan.beats, IntervalClock.beats). In a plan of steps, a rest between two different moves is a changeover and sits on the floor, so each move's sets read as one group. Pass progress to play it.
  • IntervalField maps each phase to a block in one place: work in the plan's block, rest in a calm one, "Get ready" and the cool-down in the deepest. Every family paints its own fields, with the ink computed for each block.
  • In the session, pause with the middle button, skip back and forward beside it, and hold the close button to end, so a stray tap never stops a workout. The screen stays awake while it runs, and onFinish receives an IntervalSummary with the total, the work time, the rounds and whether it ran to the end. When it ends, the same field settles into Done with the total and the rounds.
  • Haptics are on by default: a light tap on each of the last three seconds of a phase and a firmer one as the next begins. .intervalHaptics(false) turns them off for everything inside, and .intervalSounds(true) adds count-in tones, synthesized on the fly so there are no audio files to ship. Unless your app has set up its own audio session, the tones mix with the person's music and follow the silent switch. A run that plays somewhere else cues with .intervalCues(for: run).
  • VoiceOver reads the phase, the move, the round and the seconds left. The session is adjustable, so swiping up or down skips, and a magic tap pauses. The stepper tiles are adjustable too, and the format chips report their rhythm.
  • Reduce Motion keeps the heat still instead of swelling, steps the rising level once a second and turns the countdown into a cross-fade. The strip and the totals still update. Reduce Transparency leaves Pearl's haze out of the field, so the numerals sit on flat color.
  • In Pearl the heat behind the countdown is the haze, blooming in white light so it never greys the field. Other families let their own motif swell in the same rhythm: thin rings in Neon, a half disc and a dot matrix in Graphic.
  • IntervalTimerExample at the end of IntervalTimer.swift is the screen in the preview, the Timer tab of a native four-tab TabView. Copy it as a starting point.