SwiftUI 运行 按住按钮时定期编码; 运行 刚点击时代码不同?

SwiftUI run code periodically while button is being held down; run different code when it is just tapped?

我想做的是实现一个按钮,当它被按住时 运行 每 0.5 秒执行一次特定的代码行(它可以无限期地被按住,因此 运行打印语句无限期)。我希望它在被点击时有不同的行为。这是代码:

struct ContentView: View {
@State var timeRemaining = 0.5
let timer = Timer.publish(every: 0.5, on: .main, in: .common).autoconnect()
@State var userIsPressing = false //detecting whether user is long pressing the screen

var body: some View {
    VStack {
       Image(systemName: "chevron.left").onReceive(self.timer) { _ in
           if self.userIsPressing == true {
             if self.timeRemaining > 0 {
                self.timeRemaining -= 0.5
              }
            //resetting the timer every 0.5 secdonds and executing code whenever //timer reaches 0

     if self.timeRemaining == 0 {
            print("execute this code")
            self.timeRemaining = 0.5
         }
        }
    }.gesture(LongPressGesture(minimumDuration: 0.5)
                   .onChanged() { _ in
                       //when longpressGesture started
                   self.userIsPressing = true
                   }
                   .onEnded() { _ in
                       //when longpressGesture ended
                   self.userIsPressing = false

                   }
                   )
           }
}
}

目前,这与我需要它做的有点相反;上面的代码 运行 当我单击按钮时无限期地打印语句但是当我按住它时,它只执行一次...我该如何解决这个问题?

这是一个解决方案 - 要获得连续按压,需要将长按手势与顺序拖动相结合,并在处理程序中添加计时器。

更新: 使用 Xcode 11.4 / iOS 13.4(在预览和模拟器中)测试

struct TimeEventGeneratorView: View {
    var callback: () -> Void
    private let timer = Timer.publish(every: 0.5, on: .main, in: .common).autoconnect()

    var body: some View {
        Color.clear
            .onReceive(self.timer) { _ in
                self.callback()
            }
    }
}

struct TestContinuousPress: View {

    @GestureState var pressingState = false // will be true till tap hold
    var pressingGesture: some Gesture {
        LongPressGesture(minimumDuration: 0.5).sequenced(before:
              DragGesture(minimumDistance: 0, coordinateSpace:
              .local)).updating($pressingState) { value, state, transaction in
                switch value {
                    case .second(true, nil):
                        state = true
                    default:
                        break
                }
            }.onEnded { _ in
            }
    }

    var body: some View {
        VStack {
            Image(systemName: "chevron.left")
                .background(Group { if self.pressingState { TimeEventGeneratorView {
                    print(">>>> pressing: \(Date())")
                }}})
            .gesture(TapGesture().onEnded {
                print("> just tap ")
            })
            .gesture(pressingGesture)
        }
    }
}