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 touch
I took a different approach when coming up with my own solution. I created a UIButton subclass and enclosed all the solution inside. The difference is that instead of using an IBAction for the handler I created a property in the UIButton
class RapidFireButton: UIButton {
private var rapidFireTimer: Timer?
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
commonInit()
}
init() {
super.init(frame: .zero)
commonInit()
}
private func commonInit() {
addTarget(self, action: #selector(touchDownHandler), for: .touchDown)
addTarget(self, action: #selector(touchUpHandler), for: .touchUpOutside)
addTarget(self, action: #selector(touchUpHandler), for: .touchUpInside)
}
@objc private func touchDownHandler() {
rapidFireTimer?.invalidate()
rapidFireTimer = nil
tapHandler(self)
rapidFireTimer = Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true, block: { [unowned self] (timer) in
self.tapHandler(self)
})
}
@objc private func touchUpHandler() {
rapidFireTimer?.invalidate()
rapidFireTimer = nil
}
var tapHandler: (RapidFireButton) -> Void = { button in
}
}
Usage is basically creating an outlet for the button and implementing the handler like so
rapidFireButton.tapHandler = { button in
//do stuff
}