当前位置:  开发笔记 > 运维 > 正文

用于"重复射击"的按下按钮

如何解决《用于"重复射击"的按下按钮》经验,为你挑选了2个好方法。

我已经提到了关于按下按钮的无数其他问题,但与Swift没有太多关联.我使用touchUpInside事件将一个功能连接到一个按钮:

@IBAction func singleFire(sender: AnyObject){
    //code
}

...和另一个功能,用于在按住相同按钮时重复调用上述功能,并在不再按下按钮时停止:

@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()
    }
}

我不确定我做错了什么,我不知道如何将触摸事件设置为同一个按钮以实现不同的功能.



1> vacawama..:

按住按钮时,您希望快速重复射击.

buttonDownbuttonUp方法需要在顶层定义,而不是在另一个函数内定义.出于演示目的,@IBAction从Storyboard中放弃连接更简洁,只需设置按钮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](她俩润色事件),并呼吁singleFire在初始buttonDown的单火.通过这些更改,按下按钮会立即触发,然后0.3只要按住按钮,就会每秒触发一次.


该按钮可以在故事板中连接,而不是在其中进行设置viewDidLoad.在这种情况下,添加@IBActionbuttonDownbuttonUp.然后Control-点击你的故事板左键并拖动,从旁边的圆圈向下触摸func buttonDown,并拖动从旁边的圆圈触摸的内心润色外func buttonUp.

在此输入图像描述


而不是`[.TouchUpInside,.TouchUpOutside]`,你可能想要`[.TouchUpInside,.TouchDragExit]`(即如果用户将手指从火开按钮上移开,你真的想继续射击吗?).它只取决于所需的用户体验.

2> Rob..:

在我的原始答案中,我回答了如何让按钮同时识别水龙头和长按的问题.在澄清的问题中,只要用户按下手指,您就会希望此按钮持续"触发".如果是这种情况,则只需要一个手势识别器.

例如,在Interface Builder中,将长按手势识别器从对象库拖到按钮上,然后将"最小持续时间"设置为零:

在此输入图像描述

然后你可以control从长按手势识别器中拖动到助手编辑器中的代码并添加一个@IBAction来处理长按:

var timer: NSTimer?

@IBAction func longPressHandler(gesture: UILongPressGestureRecognizer) {
    if gesture.state == .Began {
        timer = NSTimer.scheduledTimerWithTimeInterval(0.3, target: self, selector: "handleTimer:", userInfo: nil, repeats: true)
    } else if gesture.state == .Ended || gesture.state == .Cancelled {
        timer?.invalidate()
        timer = nil
    }
}

func handleTimer(timer: NSTimer) {
    NSLog("bang")
}

或者,如果您还想在用户将手指拖离按钮时停止触发,请添加对手势位置的检查:

@IBAction func longPressHandler(gesture: UILongPressGestureRecognizer) {
    if gesture.state == .Began {
        timer = NSTimer.scheduledTimerWithTimeInterval(0.3, target: self, selector: "handleTimer:", userInfo: nil, repeats: true)
    } else if gesture.state == .Ended || gesture.state == .Cancelled || (gesture.state == .Changed && !CGRectContainsPoint(gesture.view!.bounds, gesture.locationInView(gesture.view))) {
        timer?.invalidate()
        timer = nil
    }
}

我的原始答案,回答了如何识别按钮上的水龙头和长按的不同问题,如下所示:


就个人而言,我会使用点按和长按手势识别器,例如:

override func viewDidLoad() {
    super.viewDidLoad()

    let longPress = UILongPressGestureRecognizer(target: self, action: "handleLongPress:")
    button.addGestureRecognizer(longPress)

    let tap = UITapGestureRecognizer(target: self, action: "handleTap:")
    tap.requireGestureRecognizerToFail(longPress)
    button.addGestureRecognizer(tap)
}

func handleTap(gesture: UITapGestureRecognizer) {
    print("tap")
}

func handleLongPress(gesture: UILongPressGestureRecognizer) {
    if gesture.state == .Began {
        print("long press")
    }
}

如果您愿意,通过长按手势,您也可以执行您的操作.Ended.它只取决于所需的用户体验.

仅供参考,您也可以在Interface Builder中添加这两个手势识别器(只需将对象库中的相应手势拖到按钮上,然后control从手势识别器拖动到@IBAction功能),但更容易说明是什么以编程方式显示它.


感谢您的编辑,这个和其他答案对我帮助很大 - 我希望我可以勾选它们.
推荐阅读
大大炮
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有