【问题标题】:Continuous Touch in SwiftSwift 中的连续触摸
【发布时间】:2019-04-09 21:38:28
【问题描述】:

目标是在按钮保持触摸期间每 0.5 秒执行一次操作,并在触摸结束时停止该操作。根据 SO 中其他帖子的建议,我采用了一种利用布尔值的策略,该布尔值在 touchDown 时设置为 true,在 touchUp 时设置为 false。但是,似乎 touchUp 函数没有设置布尔值,或者 touchDown 忽略了它,因为当我将取景器从按钮上移开时,动作仍在继续。

这是我的触摸代码:

// MARK: - Touches

func touchDown(atPoint pos : CGPoint) {
    print("Touched Down in \(purpose) down arrow")

    arrowIsPressed = true
    self.texture = SKTexture(imageNamed: "bottomArrowPressed.png")

    adjustBlue() // Because you want one immediate action, in case there is no continuous touch

    while arrowIsPressed == true {
        perform(#selector(callback), with: nil, afterDelay: 1.0)
    }
}

func touchUp(atPoint pos : CGPoint) {

    arrowIsPressed = false
    self.texture = SKTexture(imageNamed: "bottomArrow.png")

    adjustCounter = 0
}

// MARK: - Touch Helpers

@objc func callback() {

    self.adjustBlue()
}


func adjustBlue() {
    adjustCounter += 1
    print("Adjust Action \(adjustCounter)")
    // eventually useful code will go here
}

请注意,这是一个很小的按钮,我完全不关心跟踪多次触摸。

我的逻辑哪里出错了?我觉得这是一个相当直接的问题和解决方案,但我做错了什么,我无法理解。

更新:通过在 while 循环中放置一个 print 语句,我看到 while 循环被一遍又一遍地快速调用,即使我在其中有一个延迟 0.5 秒的 perform 语句。不知道为什么...

【问题讨论】:

    标签: swift touch


    【解决方案1】:

    我的直觉告诉你,你的 while 循环阻塞了主线程。

    while 不会在迭代之间延迟,而是会延迟回调的调用。循环之间没有延迟,因此主线程被阻塞,并且 touchup 函数没有机会运行。

    你可以改成

    func touchDown(atPoint pos : CGPoint) {
         print("Touched Down in \(purpose) down arrow")
    
        arrowIsPressed = true
         self.texture = SKTexture(imageNamed: "bottomArrowPressed.png")
    
         adjustBlue() // Because you want one immediate action, in case there is no continuous touch
    
         callback()
     }
    
    func touchUp(atPoint pos : CGPoint) {
    
        arrowIsPressed = false
        self.texture = SKTexture(imageNamed: "bottomArrow.png")
    
        adjustCounter = 0
    }
    
    // MARK: - Touch Helpers
    
    @objc func callback() {
          adjustBlue()
    
        // loop in a non blocking way after 0.5 seconds
          DispatchQueue.main.asynAfter(deadline: .now() + 0.5) {
                if self.arrowIsPressed {
                   self.callback()
                }
           }
    }
    
    
    
    func adjustBlue() {
        adjustCounter += 1
        print("Adjust Action \(adjustCounter)")
        // eventually useful code will go here
    }
    

    【讨论】:

    • 这很好用。为了仅在触摸持续至少 0.5 秒时重复启动,我在 Touch Down 代码中添加了另一个 DispatchQueue,该代码在 0.5 秒后测试按下,然后回调本身每 0.1 秒重复一次。
    猜你喜欢
    • 2016-11-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多