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

Posted

技术标签:

【中文标题】按住按钮时,SwiftUI 会定期运行代码;刚刚点击时运行不同的代码?【英文标题】:SwiftUI run code periodically while button is being held down; run different code when it is just tapped? 【发布时间】: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

                   
                   )
           


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

【问题讨论】:

【参考方案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,预览和运行时行为不同的罕见情况。请参阅使用更正和测试的变体进行更新。

以上是关于按住按钮时,SwiftUI 会定期运行代码;刚刚点击时运行不同的代码?的主要内容,如果未能解决你的问题,请参考以下文章

SwiftUI:如何更改用户按住导航链接或按钮等内容时发生的颜色变化?

如何指定或更改按钮 SwiftUI 的可点击区域

如何阻止我的所有 SWIFTUI 按钮一起切换?

页面控制器发生了变化,但 Carousel 没有 SwiftUI

在 Android Studio 中按住时如何更改按钮的背景颜色?

只有按住按钮并且鼠标移动时,字符才会连续移动