【问题标题】:SwiftUI run code periodically while button is being held down; run different code when it is just tapped?按住按钮时,SwiftUI 会定期运行代码;刚刚点击时运行不同的代码?
【发布时间】:2020-06-13 00:12:01
【问题描述】:

我想要做的是实现一个按钮,它在被按住时每 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

                   }
                   )
           }
}
}

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

【问题讨论】:

    标签: swift xcode timer swiftui gesture


    【解决方案1】:

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

    更新:已使用 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)
            }
        }
    }
    

    【讨论】:

    • 它永远不会打印“>>>> 按下:(Date())”...当我按住按钮时,我在终端中得到的所有输出都是“修改期间的状态”在 switch 语句的 case .second 正文中查看更新。
    • @nickcoding,预览和运行时行为不同的罕见情况。请参阅使用更正和测试的变体进行更新。
    猜你喜欢
    • 1970-01-01
    • 2020-10-23
    • 1970-01-01
    • 2012-09-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多