Profile
Back to NewsBack
GitHub Trending 3 min
Reader Mode
fulldecent/FDWaveformView: Reads an audio file and displays the waveform

fulldecent/FDWaveformView: Reads an audio file and displays the waveform

FDWaveformView

ci</a>

FDWaveformView displays audio waveforms in Swift apps so users can preview audio, scrub, and pick positions with ease.

:hatching_chick: Virtual tip jar:

Usage

Add an FDWaveformView programmatically, then load audio. If your file is missing an extension, see the Stack Overflow answer on AVURLAsset without extensions.

let thisBundle = Bundle(for: type(of: self))
let url = thisBundle.url(forResource: "Submarine", withExtension: "aiff")
self.waveform.audioURL = url

!Waveform overview showing loaded audio

Features

Highlight playback

Highlight a portion of the waveform to show progress.

self.waveform.highlightedSamples = 0..<(self.waveform.totalSamples / 2)

!Waveform with highlighted progress

Zoom for detail

Render only the visible portion while progressively adding detail as you zoom.

self.waveform.zoomSamples = 0..<(self.waveform.totalSamples / 4)

!Zoomed waveform segment

Gesture control

Allow scrubbing, stretching, and scrolling with built-in gestures.

self.waveform.doesAllowScrubbing = true
self.waveform.doesAllowStretch = true
self.waveform.doesAllowScroll = true

!Gesture-driven waveform interaction

Animated updates

Animate property changes for smoother UI feedback.

UIView.animate(withDuration: 0.3) {
    let randomNumber = arc4random() % self.waveform.totalSamples
    self.waveform.highlightedSamples = 0 ..< randomNumber
}

!Animated waveform highlight change

Rendering quality

  • Antialiased waveforms draw extra pixels to avoid jagged edges.
  • Autolayout-driven size changes trigger re-rendering to prevent pixelation.
  • Supports iOS 15+, visionOS 1+, and Swift tools version 5.10, as declared in Package.swift.
  • Includes unit tests that run on GitHub Actions.

Installation

Add this package with Swift Package Manager. In Xcode that is File > Add Package Dependencies...

API

Following is the complete API for this module:

  • FDWaveformView (open class, subclass of UIView)
- init() (public init) default initializer - delegate: FDWaveformViewDelegate? (open var, get/set) delegate for loading and rendering callbacks - audioURL: URL? (open var, get/set) audio file to render asynchronously - totalSamples: Int (open var, get) sample count of the loaded asset - highlightedSamples: CountableRange? (open var, get/set) range tinted with progressColor - zoomSamples: CountableRange (open var, get/set) range currently displayed - doesAllowScrubbing: Bool (open var, get/set) enable tap and pan scrubbing - doesAllowStretch: Bool (open var, get/set) enable pinch-to-zoom - doesAllowScroll: Bool (open var, get/set) enable panning across the waveform - wavesColor: UIColor (open var, get/set) tint for the base waveform image - progressColor: UIColor (open var, get/set) tint for the highlighted waveform - loadingInProgress: Bool (open var, get) indicates async load in progress
  • FDWaveformViewDelegate (@objc public protocol)
- waveformViewWillRender(_ waveformView: FDWaveformView) (optional) - waveformViewDidRender(_ waveformView: FDWaveformView) (optional) - waveformViewWillLoad(_ waveformView: FDWaveformView) (optional) - waveformViewDidLoad(_ waveformView: FDWaveformView) (optional) - waveformDidBeginPanning(_ waveformView: FDWaveformView) (optional) - waveformDidEndPanning(_ waveformView: FDWaveformView) (optional) - waveformDidEndScrubbing(_ waveformView: FDWaveformView) (optional)

A couple other things are exposed that we do not consider public API:

  • FDWaveformView (implements UIGestureRecognizerDelegate)
- gestureRecognizer(_:shouldRecognizeSimultaneouslyWith:) -> Bool

Testing

GitHub Actions runs the suite on the macOS 15 image with Xcode 16.4. That image provides an iPhone 16 simulator on iOS 18.5. The command is:

xcodebuild test -scheme FDWaveformView -destination 'platform=iOS Simulator,name=iPhone 16,OS=18.5'

On another Xcode, list the simulators that copy of Xcode can see and pass one of those ids. xcodebuild only accepts destinations from the selected Xcode, so an id printed by a different install will fail.

xcrun simctl list devices available | grep iPhone
xcodebuild test -scheme FDWaveformView -destination 'id=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'

The Example app target deploys to iOS 18.6, so its simulator has to be iOS 18.6 or newer:

xcodebuild build -project Example/Example.xcodeproj -scheme Example -destination 'id=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'

Contributing

Chat with me