SwiftUIのSliderが全然カスタマイズができないので自作のカスタムSlider作成してみた!
こんにちは!リーさんです🐳
とある案件でSliderを使うことになり、あまり実装したことなかったので
調べてみると全然カスタマイズできないやないか。。。。。
デザインが結構おしゃれなスライダーになるので、Apple提供のものでは作れないと思い、カスタマイズSliderを作成してみました!
今回はメモ用なのでデザイン部分は適当にやってます。
とりあえず動くものとしてのコードになるのでご了承ください☠️
import SwiftUI
struct ContentView: View {
@State private var sliderValue: Double = 0
let maxValue: Double = 100
var body: some View {
CustomSlider(value: $sliderValue, range: 0...maxValue) {
print("スライダーが終わった後の処理")
}
.frame(width: .infinity, height: 50)
.padding(.horizontal, 20)
}
}
struct CustomSlider: View {
@Binding var value: Double
@State private var isSliding = false
var range: ClosedRange<Double>
var onEnded: () -> Void
var body: some View {
GeometryReader { geometry in
let dragGesture = DragGesture(minimumDistance: 0)
.onChanged { gesture in
let newValue = value + Double(gesture.translation.width) * (range.upperBound - range.lowerBound) / Double(geometry.size.width)
value = min(max(range.lowerBound, newValue), range.upperBound)
self.isSliding = true
}
.onEnded { _ in
onEnded()
self.isSliding = false
}
ZStack {
Capsule()
.foregroundColor(.gray)
.frame(height: 20)
Capsule()
.fill(Color.blue)
.frame(width: CGFloat(self.value - self.range.lowerBound) / CGFloat(self.range.upperBound - self.range.lowerBound) * geometry.size.width, height: 20)
.offset(x: -geometry.size.width / 2 + CGFloat(self.value - self.range.lowerBound) / CGFloat(self.range.upperBound - self.range.lowerBound) * geometry.size.width / 2, y: 0)
handleButton
.foregroundColor(.blue)
.frame(width: 30, height: 30)
.gesture(dragGesture)
.offset(x: CGFloat((value - range.lowerBound) / (range.upperBound - range.lowerBound)) * geometry.size.width - geometry.size.width / 2)
if isSliding {
Text("\(value)")
.font(.system(size:50).bold())
.padding(.bottom, 100)
}
}
}
}
// MEMO: つまみ部分のカスタマイズ
var handleButton: some View {
ZStack {
Rectangle()
.fill(Color.blue)
.frame(width: 30, height: 30)
.cornerRadius(8)
HStack(spacing: 2) {
Rectangle()
.fill(Color.white)
.frame(width: 3, height: 10)
Rectangle()
.fill(Color.white)
.frame(width: 3, height: 10)
}
}
}
}
@main
struct MyApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
こちらは動作動画になります!!