连续触摸 Swift
Continuous Touch in Swift
目标是只要在按钮上保持触摸,就每 .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 循环被一次又一次地非常快速地调用,即使我在其中有一个 perform 语句有 0.5 秒的延迟。不知道为什么...
我的直觉告诉我你的 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
}
目标是只要在按钮上保持触摸,就每 .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 循环被一次又一次地非常快速地调用,即使我在其中有一个 perform 语句有 0.5 秒的延迟。不知道为什么...
我的直觉告诉我你的 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
}