Skip to content

Instantly share code, notes, and snippets.

@cwalo
Last active July 9, 2024 21:36
Show Gist options
  • Save cwalo/2029189001639e4ad4620642c62607c7 to your computer and use it in GitHub Desktop.
Save cwalo/2029189001639e4ad4620642c62607c7 to your computer and use it in GitHub Desktop.
IndentScrollView - A paging ScrollView that tracks the target content view
import SwiftUI
struct IndentScrollView: View {
let min = 0.5
let max = 3.5
let increment = 0.1
@State
var multiplier = 0.5
@State
var step: Double? = 0.5
var body: some View {
VStack {
Text("\(String(format: "%.1f", multiplier))x")
.foregroundStyle(Color.green)
.font(.headline)
GeometryReader { geo in
ScrollView(.horizontal, showsIndicators: false) {
HStack(spacing: 20) {
// !!IMPORTANT!!
// ForEach implicitly applies an id to the content view
// without this $step does not update
ForEach(Array(stride(from: min, to: max + increment, by: increment)), id: \.self) { index in
Rectangle()
.foregroundStyle(Color.gray)
.frame(width: 2)
.overlay {
if step == index {
Color.green
}
}
}
}
.scrollTargetLayout()
.padding(.horizontal, geo.frame(in: .local).midX)
}
.scrollTargetBehavior(.viewAligned)
.scrollPosition(id: $step, anchor: .trailing)
.mask(
LinearGradient(gradient: Gradient(colors: [.black, .black.opacity(0.1)]),
startPoint: .center,
endPoint: .leading)
)
.mask(
LinearGradient(gradient: Gradient(colors: [.black, .black.opacity(0.1)]),
startPoint: .center,
endPoint: .trailing)
)
}
}
.padding()
.background(Color.black)
.frame(width: 300, height: 100)
.onChange(of: step) { oldValue, newValue in
guard let newValue else { return }
multiplier = newValue
}
}
}
@cwalo
Copy link
Author

cwalo commented Dec 15, 2023

A la Spotify's podcast speed control
Screenshot 2023-12-15 at 2 28 06 AM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment