### Customizing WaveformScrubber with BarDrawer Configuration Source: https://github.com/lkora/waveformscrubber/blob/main/README.md Shows how to customize the `BarDrawer` for WaveformScrubber. This example configures the width, spacing, minimum height, and corner radius of the bars, providing a more tailored visual appearance for the waveform. ```swift WaveformScrubber( drawer: BarDrawer(config: .init(barWidth: 4, spacing: 5, minBarHeight: 4, cornerRadius: 2)), url: audioURL, progress: $progress ) ``` -------------------------------- ### SwiftUI WaveformScrubber Multi-Drawer Comparison Source: https://context7.com/lkora/waveformscrubber/llms.txt Demonstrates how to display and compare different WaveformScrubber drawer styles side-by-side within a single SwiftUI view. This example utilizes a ScrollView and VStack to arrange multiple WaveformScrubber instances, each configured with a different drawer (BarDrawer, LineDrawer, BezierCurveDrawer) and customizable styles. It also includes a Slider for interactive progress control. ```swift import SwiftUI import WaveformScrubber struct DrawerComparisonView: View { private let audioURL = Bundle.main.url(forResource: "audio", withExtension: "mp3")! @State private var progress: CGFloat = 0.45 var body: some View { ScrollView { VStack(spacing: 25) { drawerSection(title: "Bar Drawer", drawer: BarDrawer()) drawerSection(title: "Line Drawer", drawer: LineDrawer()) drawerSection( title: "Bezier Curve Drawer", drawer: BezierCurveDrawer() ) drawerSection( title: "Line Drawer (Inverted)", drawer: LineDrawer(config: .init(inverted: true)) ) Slider(value: $progress) .padding() Text("Progress: \(Int(progress * 100))%") .font(.caption) } .padding() } } @ViewBuilder func drawerSection( title: String, drawer: D ) -> some View { VStack(alignment: .leading, spacing: 8) { Text(title) .font(.headline) WaveformScrubber( drawer: drawer, url: audioURL, progress: $progress ) .waveformScrubberStyle( DefaultWaveformScrubberStyle( active: .blue, inactive: .blue.opacity(0.3) ) ) .frame(height: 80) } } } ``` -------------------------------- ### Style Waveform with Gradients and ShapeStyles Source: https://github.com/lkora/waveformscrubber/blob/main/README.md Utilize any `ShapeStyle`, including gradients and materials, for the active and inactive portions of the waveform. This example demonstrates a linear gradient for the active part. ```swift let activeGradient = LinearGradient(colors: [.cyan, .blue], startPoint: .top, endPoint: .bottom) WaveformScrubber(drawer: BezierCurveDrawer(), url: audioURL, progress: $progress) .waveformScrubberStyle( DefaultWaveformScrubberStyle( active: activeGradient, inactive: Color.gray.opacity(0.25) ) ) ``` -------------------------------- ### WaveformDrawing Protocol: Implement Custom Waveform Visualization with CircleDrawer (SwiftUI) Source: https://context7.com/lkora/waveformscrubber/llms.txt Provides an example of creating a custom waveform visualization by implementing the `WaveformDrawing` protocol. The `CircleDrawer` creates a series of circles based on audio samples, allowing for unique visual representations. Requires SwiftUI and WaveformScrubber. ```swift import SwiftUI import WaveformScrubber struct CircleDrawer: WaveformDrawing { var upsampleStrategy: UpsampleStrategy = .smooth let circleSpacing: CGFloat init(circleSpacing: CGFloat = 8) { self.circleSpacing = circleSpacing } func draw(samples: [Float], in rect: CGRect) -> Path { Path { path in let midY = rect.height / 2 for (index, sample) in samples.enumerated() { let x = CGFloat(index) * circleSpacing let radius = CGFloat(sample) * (rect.height / 4) path.addEllipse(in: CGRect( x: x - radius / 2, y: midY - radius / 2, width: radius, height: radius )) } } } func sampleCount(for size: CGSize) -> Int { guard circleSpacing > 0 else { return 0 } return Int(size.width / circleSpacing) } } struct CustomDrawerView: View { private let audioURL = Bundle.main.url(forResource: "audio", withExtension: "mp3")! @State private var progress: CGFloat = 0.5 var body: some View { WaveformScrubber( drawer: CircleDrawer(circleSpacing: 10), url: audioURL, progress: $progress ) .frame(height: 100) .padding() } } ``` -------------------------------- ### Implement Custom WaveformScrubber Style in Swift Source: https://context7.com/lkora/waveformscrubber/llms.txt Demonstrates how to create a custom style for WaveformScrubber by conforming to the WaveformScrubberStyle protocol. This involves defining colors and applying shadows for visual effects. The example shows a ShadowWaveformStyle and its usage within a SwiftUI View. ```swift import SwiftUI import WaveformScrubber struct ShadowWaveformStyle: WaveformScrubberStyle { let activeColor: Color let inactiveColor: Color let shadowRadius: CGFloat init(active: Color, inactive: Color, shadowRadius: CGFloat = 5) { self.activeColor = active self.inactiveColor = inactive self.shadowRadius = shadowRadius } func makeBody(configuration: Configuration) -> some View { ZStack { configuration.inactiveWaveform .foregroundStyle(inactiveColor) configuration.activeWaveform .foregroundStyle(activeColor) .shadow(color: activeColor.opacity(0.6), radius: shadowRadius) } } } struct CustomStyleView: View { private let audioURL = Bundle.main.url(forResource: "audio", withExtension: "mp3")! @State private var progress: CGFloat = 0.4 var body: some View { WaveformScrubber( drawer: BezierCurveDrawer(), url: audioURL, progress: $progress ) .waveformScrubberStyle( ShadowWaveformStyle( active: .cyan, inactive: .gray.opacity(0.3), shadowRadius: 8 ) ) .frame(height: 120) .padding() } } ``` -------------------------------- ### Line Drawer Waveform with Inverted Style Option (SwiftUI) Source: https://context7.com/lkora/waveformscrubber/llms.txt Shows how to use the LineDrawer for WaveformScrubber, including an option to display the waveform with an inverted (cutout) effect. This example requires SwiftUI and WaveformScrubber and demonstrates two distinct visual styles for line-based waveforms. ```swift import SwiftUI import WaveformScrubber struct LineWaveformView: View { private let audioURL = Bundle.main.url(forResource: "audio", withExtension: "mp3")! @State private var progress: CGFloat = 0.0 var body: some View { VStack(spacing: 20) { Text("Normal Line Style") WaveformScrubber( drawer: LineDrawer(config: .init(inverted: false)), url: audioURL, progress: $progress ) .frame(height: 80) Text("Inverted (Cutout) Style") WaveformScrubber( drawer: LineDrawer(config: .init(inverted: true)), url: audioURL, progress: $progress ) .frame(height: 80) } .padding() } } ``` -------------------------------- ### Add WaveformScrubber Dependency via Swift Package Manager Source: https://context7.com/lkora/waveformscrubber/llms.txt Shows how to add the WaveformScrubber library as a dependency in your Swift package. This involves specifying the Git repository URL and the branch to use. The example includes platform compatibility settings. ```swift // Package.swift import PackageDescription let package = Package( name: "MyApp", platforms: [ .iOS(.v16), .macOS(.v12), .watchOS(.v8), .visionOS(.v1) ], dependencies: [ .package( url: "https://github.com/lkora/WaveformScrubber.git", branch: "main" ) ], targets: [ .target( name: "MyApp", dependencies: ["WaveformScrubber"] ) ] ) ``` -------------------------------- ### WaveformScrubber Solid Color Style in SwiftUI Source: https://context7.com/lkora/waveformscrubber/llms.txt Applies solid colors to the active and inactive portions of a WaveformScrubber using the DefaultWaveformScrubberStyle. This example demonstrates setting custom colors for the waveform segments. It requires SwiftUI and the WaveformScrubber library. ```swift import SwiftUI import WaveformScrubber struct SolidColorStyleView: View { private let audioURL = Bundle.main.url(forResource: "audio", withExtension: "mp3")! @State private var progress: CGFloat = 0.4 var body: some View { WaveformScrubber( drawer: BarDrawer(), url: audioURL, progress: $progress ) .waveformScrubberStyle( DefaultWaveformScrubberStyle( active: .purple, inactive: .purple.opacity(0.3) ) ) .frame(height: 100) .padding() } } ``` -------------------------------- ### Basic Waveform Display with Bar Drawer (SwiftUI) Source: https://context7.com/lkora/waveformscrubber/llms.txt Demonstrates the basic usage of WaveformScrubber with the default BarDrawer for visualizing audio waveforms and enabling scrubbing. It requires SwiftUI and WaveformScrubber, takes an audio URL and a progress binding, and outputs a visual waveform with scrubbing capabilities. ```swift import SwiftUI import WaveformScrubber struct BasicExampleView: View { private let audioURL = Bundle.main.url(forResource: "example", withExtension: "mp3")! @State private var progress: CGFloat = 0.25 var body: some View { VStack { Text("Playback Progress: \(Int(progress * 100))%") WaveformScrubber( drawer: BarDrawer(), url: audioURL, progress: $progress ) .frame(height: 100) .padding() Slider(value: $progress) .padding() } } } ``` -------------------------------- ### WaveformScrubber Callbacks for Events Source: https://github.com/lkora/waveformscrubber/blob/main/README.md Implement callbacks to react to waveform events such as metadata loading and user scrubbing gestures. `onInfoLoaded` provides audio metadata, and `onGestureActive` indicates when the user is interacting with the scrubber. ```swift WaveformScrubber( drawer: BarDrawer(), url: audioURL, progress: $progress, onInfoLoaded: { audioInfo in // Fired once the audio file's metadata is available. print("Audio duration: \(audioInfo.duration)") }, onGestureActive: { isDragging in // Fired when the user starts or stops dragging the waveform. if isDragging { print("User is scrubbing.") } else { print("User finished scrubbing.") } } ) ``` -------------------------------- ### Basic WaveformScrubber Usage in SwiftUI Source: https://github.com/lkora/waveformscrubber/blob/main/README.md Demonstrates the basic integration of WaveformScrubber in a SwiftUI view. It requires an audio file URL and a binding for the playback progress. The default `BarDrawer` is used, and the waveform's height can be adjusted. A `Slider` is included to control the progress externally. ```swift import SwiftUI import WaveformScrubber struct BasicExampleView: View { // URL to your audio file private let audioURL = Bundle.main.url(forResource: "example", withExtension: "mp3")! @State private var progress: CGFloat = 0.25 var body: some View { VStack { Text("Playback Progress: \(Int(progress * 100))%") WaveformScrubber( drawer: BarDrawer(), // The default bar-style drawer url: audioURL, progress: $progress ) .frame(height: 100) .padding() // Control the progress from outside Slider(value: $progress) .padding() } } } ``` -------------------------------- ### WaveformScrubber: Handle Audio Metadata and User Interaction Events (SwiftUI) Source: https://context7.com/lkora/waveformscrubber/llms.txt Shows how to use the WaveformScrubber's callback methods to react to audio metadata loading (onInfoLoaded) and user scrubbing gestures (onGestureActive). This allows for dynamic UI updates based on audio state and user interaction. Requires SwiftUI and WaveformScrubber. ```swift import SwiftUI import WaveformScrubber struct CallbackExampleView: View { private let audioURL = Bundle.main.url(forResource: "audio", withExtension: "mp3")! @State private var progress: CGFloat = 0.0 @State private var audioDuration: TimeInterval = 0 @State private var isUserScrubbing: Bool = false @State private var statusMessage: String = "Loading..." var body: some View { VStack(spacing: 20) { Text("Status: (statusMessage)") .font(.headline) Text("Duration: (String(format: "%.2f", audioDuration))s") Text("Progress: (String(format: "%.1f", progress * 100))%") Text(isUserScrubbing ? "User is scrubbing" : "Not scrubbing") .foregroundColor(isUserScrubbing ? .red : .green) WaveformScrubber( drawer: BarDrawer(), url: audioURL, progress: $progress, onInfoLoaded: { audioInfo in audioDuration = audioInfo.duration statusMessage = "Audio loaded successfully" print("Audio duration: (audioInfo.duration) seconds") }, onGestureActive: { isDragging in isUserScrubbing = isDragging if isDragging { statusMessage = "User is scrubbing" print("User started scrubbing") } else { statusMessage = "Scrubbing ended" print("User finished scrubbing at (progress * 100)%") } } ) .frame(height: 100) } .padding() } } ``` -------------------------------- ### WaveformScrubber Gradient and Material Styles in SwiftUI Source: https://context7.com/lkora/waveformscrubber/llms.txt Demonstrates applying gradient and material styles to WaveformScrubber using DefaultWaveformScrubberStyle. This includes linear gradients, radial gradients, and shows how to customize the appearance of active and inactive waveform parts. Requires SwiftUI and WaveformScrubber. ```swift import SwiftUI import WaveformScrubber struct GradientStyleView: View { private let audioURL = Bundle.main.url(forResource: "audio", withExtension: "mp3")! @State private var progress: CGFloat = 0.6 var body: some View { VStack(spacing: 20) { Text("Linear Gradient") WaveformScrubber( drawer: BezierCurveDrawer(), url: audioURL, progress: $progress ) .waveformScrubberStyle( DefaultWaveformScrubberStyle( active: LinearGradient( colors: [.cyan, .blue], startPoint: .top, endPoint: .bottom ), inactive: Color.gray.opacity(0.25) ) ) .frame(height: 100) Text("Radial Gradient") WaveformScrubber( drawer: LineDrawer(), url: audioURL, progress: $progress ) .waveformScrubberStyle( DefaultWaveformScrubberStyle( active: RadialGradient( colors: [.pink, .purple], center: .center, startRadius: 10, endRadius: 100 ), inactive: .gray.opacity(0.2) ) ) .frame(height: 100) } .padding() } } ``` -------------------------------- ### WaveformScrubber Upsampling Strategies Comparison in SwiftUI Source: https://context7.com/lkora/waveformscrubber/llms.txt Compares different upsampling strategies for WaveformScrubber, including .smooth, .cosine, .linear, .hold, and .none. These strategies control how the waveform interpolates data when the view is wider than available samples. The code uses SwiftUI and the WaveformScrubber library. ```swift import SwiftUI import WaveformScrubber struct UpsamplingComparisonView: View { private let shortAudioURL = Bundle.main.url(forResource: "short", withExtension: "mp3")! @State private var progress: CGFloat = 0.5 var body: some View { VStack(spacing: 20) { Text("Smooth Interpolation (Default)") WaveformScrubber( drawer: BarDrawer(upsampleStrategy: .smooth), url: shortAudioURL, progress: $progress ) .frame(height: 60) Text("Cosine Interpolation") WaveformScrubber( drawer: BarDrawer(upsampleStrategy: .cosine), url: shortAudioURL, progress: $progress ) .frame(height: 60) Text("Linear Interpolation") WaveformScrubber( drawer: BarDrawer(upsampleStrategy: .linear), url: shortAudioURL, progress: $progress ) .frame(height: 60) Text("Hold (Blocky)") WaveformScrubber( drawer: BarDrawer(upsampleStrategy: .hold), url: shortAudioURL, progress: $progress ) .frame(height: 60) Text("No Interpolation (Gaps)") WaveformScrubber( drawer: BarDrawer(upsampleStrategy: .none), url: shortAudioURL, progress: $progress ) .frame(height: 60) } .padding() } } ``` -------------------------------- ### Configure Waveform Upsampling Strategy Source: https://github.com/lkora/waveformscrubber/blob/main/README.md Control how the waveform is upsampled when the view is wider than the available samples. Options include smooth interpolation, hold interpolation, or no interpolation. ```swift VStack { Text("Smooth Interpolation (Default)") WaveformScrubber( drawer: BarDrawer(upsampleStrategy: .smooth), url: shortAudioURL, progress: $progress ) Text("Hold Interpolation (Blocky)") WaveformScrubber( drawer: BarDrawer(upsampleStrategy: .hold), url: shortAudioURL, progress: $progress ) Text("No Interpolation (Gaps)") WaveformScrubber( drawer: BarDrawer(upsampleStrategy: .none), url: shortAudioURL, progress: $progress ) } ``` -------------------------------- ### Bezier Curve Waveform Rendering (SwiftUI) Source: https://context7.com/lkora/waveformscrubber/llms.txt Demonstrates the usage of the BezierCurveDrawer for WaveformScrubber to render smooth, organic waveform curves with adjustable curviness and pixels per sample. This SwiftUI snippet requires the WaveformScrubber library and configures a fluid visual representation of audio data. ```swift import SwiftUI import WaveformScrubber struct BezierWaveformView: View { private let audioURL = Bundle.main.url(forResource: "audio", withExtension: "mp3")! @State private var progress: CGFloat = 0.3 var body: some View { WaveformScrubber( drawer: BezierCurveDrawer( config: .init( curviness: 0.8, pixelsPerSample: 4 ) ), url: audioURL, progress: $progress ) .frame(height: 100) .padding() } } ``` -------------------------------- ### WaveformScrubber: Render as Stroke Outline with LineDrawer/BezierCurveDrawer (SwiftUI) Source: https://context7.com/lkora/waveformscrubber/llms.txt Demonstrates rendering a waveform as a stroked outline using either LineDrawer or BezierCurveDrawer. This approach is useful for emphasizing the waveform's shape without filling it. It requires SwiftUI and the WaveformScrubber library. ```swift import SwiftUI import WaveformScrubber struct StrokeStyleView: View { private let audioURL = Bundle.main.url(forResource: "audio", withExtension: "mp3")! @State private var progress: CGFloat = 0.35 var body: some View { VStack(spacing: 20) { Text("Stroke with LineDrawer") WaveformScrubber( drawer: LineDrawer(), url: audioURL, progress: $progress ) .waveformScrubberStyle( StrokeWaveformScrubberStyle( active: .orange, inactive: .orange.opacity(0.3), lineWidth: 2 ) ) .frame(height: 80) Text("Stroke with BezierCurveDrawer") WaveformScrubber( drawer: BezierCurveDrawer(), url: audioURL, progress: $progress ) .waveformScrubberStyle( StrokeWaveformScrubberStyle( active: .green, inactive: .green.opacity(0.3), lineWidth: 3 ) ) .frame(height: 80) } .padding() } } ``` -------------------------------- ### Customizing WaveformScrubber with LineDrawer Source: https://github.com/lkora/waveformscrubber/blob/main/README.md Illustrates using the `LineDrawer` for WaveformScrubber to create a solid, filled line shape. The `inverted` configuration option is demonstrated, which can be used to create a "cutout" effect on the waveform. ```swift WaveformScrubber( drawer: LineDrawer(config: .init(inverted: true)), // Create a "cutout" effect url: audioURL, progress: $progress ) ``` -------------------------------- ### Style Waveform with Stroke Source: https://github.com/lkora/waveformscrubber/blob/main/README.md Apply a stroke outline to the waveform instead of a filled shape using `StrokeWaveformScrubberStyle`. This is particularly useful for drawers like `LineDrawer` or `BezierCurveDrawer`. ```swift WaveformScrubber(drawer: LineDrawer(), url: audioURL, progress: $progress) .waveformScrubberStyle( StrokeWaveformScrubberStyle(style: .orange, lineWidth: 2) ) ``` -------------------------------- ### Customizing WaveformScrubber with BezierCurveDrawer Source: https://github.com/lkora/waveformscrubber/blob/main/README.md Presents the use of `BezierCurveDrawer` for WaveformScrubber to render a smooth, organic waveform shape. Configuration options like `curviness` and `pixelsPerSample` are available to fine-tune the curve's appearance. ```swift WaveformScrubber( drawer: BezierCurveDrawer(config: .init(curviness: 0.8, pixelsPerSample: 4)), url: audioURL, progress: $progress ) ``` -------------------------------- ### Style Waveform with Solid Colors Source: https://github.com/lkora/waveformscrubber/blob/main/README.md Apply solid colors to the active and inactive parts of the waveform using the `.waveformScrubberStyle()` modifier with `DefaultWaveformScrubberStyle`. ```swift WaveformScrubber(drawer: BarDrawer(), url: audioURL, progress: $progress) .waveformScrubberStyle( DefaultWaveformScrubberStyle( active: .purple, inactive: .purple.opacity(0.3) ) ) ``` -------------------------------- ### Add WaveformScrubber Dependency in Package.swift Source: https://github.com/lkora/waveformscrubber/blob/main/README.md Integrate the WaveformScrubber library into your project by adding it as a dependency in your Swift Package Manager `Package.swift` manifest file. ```swift // In your Package.swift: .package(url: "https://github.com/lkora/WaveformScrubber.git", branch: "main") // Add to targets: .target(name: "MyTarget", dependencies: ["WaveformScrubber"]) ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.