Jim*_*ton 1 timer swift swiftui
我正在尝试创建一个步进器,其中数字在长按手势时快速增加,并在用户释放时停止。
到目前为止,我已经在长按上获得了增量,但是当我释放计时器时,计时器仍然继续,继续增加状态。
我该如何解决当用户松开按键时计时器停止的问题。
struct CustomFoodItemView: View {
@State var foodName = ""
@State var proteinAmount = 1
@State var carbAmount = 1
@State var fatAmount = 1
@State private var timer: Timer?
@State var isLongPressing = false
var body: some View {
VStack{
VStack{
Text("Food Name")
TextField("", text: $foodName)
.multilineTextAlignment(.center)
.border(.white)
.padding(.trailing, 10)
.frame(width:100, height:10)
}
HStack{
Text(String(proteinAmount) + "g")
.frame(width:50, height:50)
Image(systemName: "plus.circle.fill")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 30, height: 30)
.foregroundColor(Color("SuccessButtonColor"))
.simultaneousGesture(LongPressGesture(minimumDuration: 0.2).onChanged { _ in
print("long press")
self.isLongPressing = true
if self.isLongPressing == true{
self.timer = Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true, block: { _ in
proteinAmount += 1
})
}
}
.onEnded { _ in
print("stopped") //why won't you stop
self.isLongPressing = false
})
}
}
Run Code Online (Sandbox Code Playgroud)
两件事情:
self.timer?.invalidate()。.onEnded被LongPressGesture识别为按下按钮时间超过minimumDuration时间时,将调用该方法,它不处理按钮释放时的事件。所以你不想停止计时器.onEnded。我尝试了您的代码,一种方法可能是使用LongPressGesture来启动计时器,并DragGesture使用最小距离 0 来识别按钮释放。
这看起来像:
struct CustomFoodItemView: View {
@State var foodName = ""
@State var proteinAmount = 0
@State var carbAmount = 0
@State var fatAmount = 0
let maxValue = 50
let minValue = 0
@State private var timer: Timer?
var body: some View {
// a drag gesture that recognizes the release of the button to stop the timer, set minimumDistance to 0 to ensure no dragging is required
let releaseGesture = DragGesture(minimumDistance: 0)
.onEnded { _ in
self.timer?.invalidate()
print("Timer stopped")
}
// a long press gesture to activate timer and start increasing the proteinAmount
let longPressGestureIncrease = LongPressGesture(minimumDuration: 0.2)
.onEnded { value in
self.timer = Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true, block: { _ in
if proteinAmount < maxValue {
proteinAmount += 1
}
})
print("Timer started")
}
// a long press gesture to activate timer and start decreasing the proteinAmount
let longPressGestureDecrease = LongPressGesture(minimumDuration: 0.2)
.onEnded { value in
self.timer = Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true, block: { _ in
if proteinAmount > minValue {
proteinAmount -= 1
}
})
print("Timer started")
}
// a combined gesture that forces the user to long press before releasing for increasing the value
let combinedIncrease = longPressGestureIncrease.sequenced(before: releaseGesture)
// a combined gesture that forces the user to long press before releasing for decreasing the value
let combinedDecrease = longPressGestureDecrease.sequenced(before: releaseGesture)
VStack{
VStack{
Text("Food Name")
TextField("", text: $foodName)
.multilineTextAlignment(.center)
.border(.white)
.padding(.trailing, 10)
.frame(width:100, height:10)
}
HStack{
Image(systemName: "minus.circle.fill")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 30, height: 30)
.foregroundColor(.red)
.gesture(combinedDecrease)
Text(String(proteinAmount) + "g")
.frame(width:50, height:50)
Image(systemName: "plus.circle.fill")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 30, height: 30)
.foregroundColor(.red)
.gesture(combinedIncrease)
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
请查看包含代码片段中的几个项目的 gif(开始长按后数字增加,释放“+”按钮时停止):
| 归档时间: |
|
| 查看次数: |
1171 次 |
| 最近记录: |