Screen · Media

Now Playing SwiftUI Screen

A music library with a floating player that grows into a full now-playing screen.

A floating now-playing capsule with a progress ring that grows into a full player under the finger: matched-geometry artwork and title, the cover above a solid control panel, favorite and more buttons, scrub and volume bars that thicken under the finger, and an optional action row.

  • SwiftUI
  • iOS 17.0+
  • mini-player
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 floating capsule with a progress ring above the tab bar
  • Expands under the finger with matched artwork and title
  • The cover above a solid control panel with a big play dial
  • Scrub and volume bars that thicken under the finger
  • Favorite, more and an optional action row

02

Implementation notes

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

At rest it is a floating capsule above the bottom edge: artwork, title and artist, a play/pause button ringed by playback progress, and skip. Tap it or drag up and it becomes the full player: height, margins and corner radius follow the finger, the artwork and title travel between the two layouts with matchedGeometryEffect, and an ambient backdrop drawn from the cover fades in behind them. Release projects the flick with predictedEndTranslation and commits with a spring and a soft haptic.

The full player has a large title row with optional favorite and more buttons, a scrub bar and a volume slider that thicken from 6pt to 12pt while held, transport controls, and an optional row of actions such as lyrics, a sleep timer or the queue. The artwork eases smaller while paused. No AVFoundation: pass a NowPlaying model, isPlaying and progress, and handle the callbacks.

Options

  • isFavorite: Binding<Bool>? adds a star to the title row.
  • volume: Binding<Double>? adds the volume slider (0 to 1).
  • actions: [MiniPlayerAction] fills the bottom row; isOn draws an action selected.
  • onMore adds an ellipsis button for your own menu or confirmation dialog.
  • tint colors the scrub, volume and transport controls. The full player always renders dark over its backdrop, so the default .primary reads white there.

Notes

  • States: capsule, dragging (rubber-banded past both ends), expanded, scrubbing, adjusting volume, playing/paused (artwork scale), favorite and actions on/off.
  • The layout switches from compact to expanded at 30% travel so the matched morph has room; below that the capsule stretches, above it the full player's controls fade in with progress.
  • Place it in a ZStack over your content; it reads the container's safe area and ignores it while expanding, so it reaches the display edges at full height. Pass bottomInset to float above a tab bar.
  • The scrub and volume gestures are child DragGestures so they win over the expand drag. VoiceOver gets adjustable actions: 15-second steps for position, 10% steps for volume.
  • Reduce Motion replaces springs with short ease-outs and skips the paused-artwork scale. Reduce Transparency swaps the material and blurred cover for opaque surfaces.
  • MiniPlayerExample at the end of MiniPlayer.swift is the screen shown in the preview; copy it as a starting point. Its covers are drawn in code (AlbumArt), so it has no asset dependency.