Screen · Education

Lessons SwiftUI Screen

A language-learning home with a streak, today's goals as color blocks and a floating tab bar whose lens follows your finger.

The home tab of a language-learning app: a greeting and level, a week streak, today's goals stacked as solid color blocks with durations, and a start-lesson action, on a floating glass tab bar whose lens follows the finger, stretches toward it and snaps with a spring. The bar hides on scroll and ships as `LensTabBar` for your own apps.

  • SwiftUI
  • iOS 17.0+
  • lens-tab-bar
Get SwiftPieces 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.

  • A lessons home with streak, level and stacked goal blocks
  • A tab bar lens that tracks and stretches toward the finger
  • Spring snap, with the selected tab expanding to its label
  • Hides on scroll through a progress value
  • The foundation of the App Shell screen

In the Build Kit

Studio (style). Your agent builds around this screen in the same design.

Used in

App Shell (screen)

02

Implementation notes

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

Tap or drag across the bar. While dragging, every tab collapses to its icon and the lens stretches toward the finger, switching selection with a haptic as it crosses each tab; on release it snaps onto the nearest tab and the selected label expands back in. Reselecting the current tab pulses the lens and calls onReselect, and scrollProgress slides the bar below the screen edge so a shell can hide it on scroll. Glass on iOS 26, Material below.

Notes

  • States: idle, dragging (icon-only, stretched lens), selected (label shown), hidden (scrollProgress at 1, removed from VoiceOver).
  • Tab frames are measured with onGeometryChange in the bar's named coordinate space; the lens is drawn from those frames, so it needs no matchedGeometryEffect.
  • The whole bar is one DragGesture(minimumDistance: 0): a release without movement is a tap, movement is a drag. Tabs still expose .isButton/.isSelected traits and an accessibility action, and the container carries .isTabBar.
  • .symbolEffect(.bounce) fires only on the tab being selected (per-tab counter), never on the one being left. Reduce Motion replaces springs with short ease-outs and skips the bounce and pulse.
  • Reduce Transparency swaps glass and Material for an opaque secondary background.
  • The screen: a greeting, a light giant streak count, the week as circles, and today's goals as full-width blocks stacked with a negative VStack spacing and rising zIndex, so each overlaps the one above. At accessibility sizes the overlap drops to zero. Goals toggle done on tap.
  • The next-lesson block crops a giant light word at its bottom edge; the word is decorative, hidden from VoiceOver and capped at a fixed Dynamic Type size. The bar is styled from the theme: a surface capsule with a solid tile(0) lens and its ink, exactly as TabShellScreen passes it.
  • LensTabBarExample at the end of LensTabBar.swift is the Lessons screen from the preview.