FDWaveformView displays audio waveforms in Swift apps so users can preview audio, scrub, and pick positions with ease.
🐣 Virtual tip jar: https://amazon.com/hz/wishlist/ls/EE78A23EEGQB
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 = urlHighlight a portion of the waveform to show progress.
self.waveform.highlightedSamples = 0..<(self.waveform.totalSamples / 2)Render only the visible portion while progressively adding detail as you zoom.
self.waveform.zoomSamples = 0..<(self.waveform.totalSamples / 4)Allow scrubbing, stretching, and scrolling with built-in gestures.
self.waveform.doesAllowScrubbing = true
self.waveform.doesAllowStretch = true
self.waveform.doesAllowScroll = trueAnimate property changes for smoother UI feedback.
UIView.animate(withDuration: 0.3) {
let randomNumber = arc4random() % self.waveform.totalSamples
self.waveform.highlightedSamples = 0 ..< randomNumber
}- Antialiased waveforms draw extra pixels to avoid jagged edges.
- Autolayout-driven size changes trigger re-rendering to prevent pixelation.
- Supports iOS 12+ and Swift 5.
- Includes unit tests that run on GitHub Actions.
Use Swift Package Manager: in Xcode choose File > Swift Packages > Add Package Dependency and point to this repository. Legacy installation options are available if needed.
Following is the complete API for this module:
-
FDWaveformView(open class, subclass ofUIView)init()(public init) default initializerdelegate: FDWaveformViewDelegate?(open var, get/set) delegate for loading and rendering callbacksaudioURL: URL?(open var, get/set) audio file to render asynchronouslytotalSamples: Int(open var, get) sample count of the loaded assethighlightedSamples: CountableRange<Int>?(open var, get/set) range tinted withprogressColorzoomSamples: CountableRange<Int>(open var, get/set) range currently displayeddoesAllowScrubbing: Bool(open var, get/set) enable tap and pan scrubbingdoesAllowStretch: Bool(open var, get/set) enable pinch-to-zoomdoesAllowScroll: Bool(open var, get/set) enable panning across the waveformwavesColor: UIColor(open var, get/set) tint for the base waveform imageprogressColor: UIColor(open var, get/set) tint for the highlighted waveformloadingInProgress: 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(implementsUIGestureRecognizerDelegate)gestureRecognizer(_:shouldRecognizeSimultaneouslyWith:) -> Bool
Find an available simulator:
xcrun simctl list devices available | grep iPhoneBuild and test using a simulator ID from the output:
# Build the library
xcodebuild build -scheme FDWaveformView -destination 'id=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'
# Run unit tests
xcodebuild test -scheme FDWaveformView -destination 'id=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'
# Build the Example app (requires a newer iOS simulator)
cd Example
xcodebuild build -scheme Example -destination 'id=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'- This project's layout is based on https://github.com/fulldecent/swift6-module-template




