用于“重复射击”的按下按钮。 [英] Press-and-hold button for "repeat fire"
问题描述
我已经提到了关于按下按钮的无数其他问题,但与Swift没有太多关联。我使用touchUpInside事件将一个函数连接到一个按钮:
I have referred to countless other questions about a press-and-hold button but there aren't many related to Swift. I have one function connected to a button using the touchUpInside event:
@IBAction func singleFire(sender: AnyObject){
//code
}
...以及另一个用于调用按住同一按钮时反复执行上述功能,并在不再按下该按钮时停止:
...and another function that is meant to call the function above repeatedly while the same button is held down, and stop when the button is no longer pressed:
@IBAction func speedFire(sender: AnyObject){
button.addTarget(self, action: "buttonDown:", forControlEvents: .TouchDown)
button.addTarget(self, action: "buttonUp:", forControlEvents: .TouchUpOutside)
func buttonDown(sender: AnyObject){
timer = NSTimer.scheduledTimerWithTimeInterval(0.3, target: self, selector: "singleFire", userInfo: nil, repeats: true)
}
func buttonUp(sender: AnyObject){
timer.invalidate()
}
}
我不确定我做错了什么,我不知道现在如何将触摸事件设置为相同的按钮以用于不同的功能。
I'm not sure what I'm doing wrong, and I don't know how to setup touch events to the same button for a different function.
推荐答案
您希望在按住按钮时快速重复触发。
You want rapid repeat fire when your button is held down.
你的 buttonDown
和 buttonUp
方法需要在顶层定义,而不是在另一个函数内定义。出于演示目的,放弃从故事板中连接 @IBAction
s更清楚,只需设置 viewDidLoad
:
Your buttonDown
and buttonUp
methods need to be defined at the top level, and not inside of another function. For demonstration purposes, it is clearer to forgo wiring up @IBAction
s from the Storyboard and just set up the button in viewDidLoad
:
class ViewController: UIViewController {
@IBOutlet weak var button: UIButton!
var timer: Timer?
var speedAmmo = 20
@objc func buttonDown(_ sender: UIButton) {
singleFire()
timer = Timer.scheduledTimer(timeInterval: 0.3, target: self, selector: #selector(rapidFire), userInfo: nil, repeats: true)
}
@objc func buttonUp(_ sender: UIButton) {
timer?.invalidate()
}
func singleFire() {
print("bang!")
}
@objc func rapidFire() {
if speedAmmo > 0 {
speedAmmo -= 1
print("bang!")
} else {
print("out of speed ammo, dude!")
timer?.invalidate()
}
}
override func viewDidLoad() {
super.viewDidLoad()
// These could be added in the Storyboard instead if you mark
// buttonDown and buttonUp with @IBAction
button.addTarget(self, action: #selector(buttonDown), for: .touchDown)
button.addTarget(self, action: #selector(buttonUp), for: [.touchUpInside, .touchUpOutside])
}
}
此外,我将 .touchUpOutside
更改为 [。touchUpInside,.touchUpOutside]
(以捕获两个补足事件)并在单个火灾的初始 buttonDown
上调用 singleFire
。通过这些更改,按下按钮会立即触发,然后只要按下按钮,每个 0.3
秒就会触发。
Also, I changed .touchUpOutside
to [.touchUpInside, .touchUpOutside]
(to catch both touch up events) and call singleFire
on the initial buttonDown
for single fire. With these changes, pressing the button fires immediately, and then fires every 0.3
seconds for as long as the button is held down.
该按钮可以在故事板中连接,而不是在 viewDidLoad
中设置。在这种情况下,将 @IBAction
添加到 buttonDown
和 buttonUp
。然后控制 - 点击故事板中的按钮,然后从触摸旁边的圆圈拖到 func buttonDown
,并从 Touch Up Inside 和 Touch Up Outside 旁边的圆圈拖动到 func buttonUp
。
The button can be wired up in the Storyboard instead of setting it up in viewDidLoad
. In this case, add @IBAction
to buttonDown
and buttonUp
. Then Control-click on your button in the Storyboard and drag from the circle next to Touch Down to func buttonDown
, and drag from the circles next to Touch Up Inside and Touch Up Outside to func buttonUp
.
这篇关于用于“重复射击”的按下按钮。的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!