Swift 時間期間スライダー
TimePeriodSlider
TimePeriodSliderを部品か出来るように切り出せるとベスト。
import Foundation
import SwiftUI
struct ClockEditView: View {
var index: Int
@EnvironmentObject var clocksData: ClocksData
@Environment(\.presentationMode) var presentationMode
@State var startProgress: CGFloat = 0.0
@State var startBarWith: CGFloat = 0.7
@State var endProgress: CGFloat = 0.7
@State var showeEndBar: Bool = false
var body: some View {
VStack {
:
:
HStack {
TimePeriodSlider()
}
:
:
}
.onAppear() {
:
}
@ViewBuilder
func TimePeriodSlider() -> some View {
GeometryReader { geometry in
let progressBarWith = geometry.size.width - 32.0
ZStack(alignment: .leading) {
Rectangle()
.strokeBorder(.yellow.opacity(1.00), style: StrokeStyle(lineWidth: 40, lineCap: .round, lineJoin: .round))
Rectangle()
.offset(x: progressBarWith * self.startProgress)
.strokeBorder(.blue, style: StrokeStyle(lineWidth: 40, lineCap: .round, lineJoin: .round))
.frame(width: progressBarWith * self.startBarWith - (progressBarWith * self.startProgress) + 32.0)
if self.showeEndBar == true {
Rectangle()
.offset(x: geometry.size.width * 0.0)
.strokeBorder(.blue, style: StrokeStyle(lineWidth: 40, lineCap: .round, lineJoin: .round))
.frame(width: progressBarWith * self.endProgress + 32.0)
}
Image(systemName: "s.circle")
.font(.callout)
.foregroundColor(.blue)
.frame(width: 32, height: 32)
.background(.white, in: Circle())
.offset(x: progressBarWith * self.startProgress)
.gesture(
DragGesture()
.onChanged({ value in
self.onDrag(value: value, with: progressBarWith)
})
)
Image(systemName: "e.circle")
.font(.callout)
.foregroundColor(.blue)
.frame(width: 32, height: 32)
.background(.white, in: Circle())
.offset(x: (geometry.size.width - 32.0) * self.endProgress)
.gesture(
DragGesture()
.onChanged({ value in
self.onDrag(value: value, with: progressBarWith, isStart: false)
})
)
}
}
.frame(width: self.screenBounds().width / 1.1,
height: 40)
}
func onDrag(value: DragGesture.Value, with: CGFloat, isStart: Bool = true) {
print(value)
print(self.screenBounds().width)
print(with)
print(self.screenBounds().width - with)
var progress = (value.location.x) / with
var dispprogress = (value.location.x) / (with)
if progress < 0.0 {
progress = 0.0
dispprogress = 0.0
}
else if progress > 1.0 {
progress = 1.0
dispprogress = (with - 32.0) / (with)
}
self.setProgress(with: with, progress: progress, dispprogress: dispprogress, isStart: isStart)
print("\(progress):\(dispprogress)")
}
func setProgress(with: CGFloat, progress: CGFloat, dispprogress: CGFloat, isStart: Bool = true) {
if isStart == true {
self.startProgress = progress
if startProgress > endProgress {
self.startBarWith = 1.0
self.showeEndBar = true
}
else {
self.startBarWith = self.endProgress
self.showeEndBar = false
}
}
else {
self.endProgress = progress
if endProgress < startProgress {
self.startBarWith = 1.0
self.showeEndBar = true
}
else {
self.startBarWith = progress
self.showeEndBar = false
}
}
}
}







