Press-and-hold button for repeat fire
You want rapid repeat fire when your button is held down.
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])
}
}
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.
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
.
Way to make a UIButton continuously fire during a press-and-hold situation?
Don't use a button, use multi-touch and NSTimer:
Make a view-local NSTimer object inside your interface, then use it to start/cancel the timer
-(void)movePlayer:(id)sender {
<Code to move player>
}
-(void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event {
timer = [NSTimer scheduledTimerWithTimeInterval:0.3 target:self selector:@selector(movePlayer:) userInfo:nil repeats:YES];
}
-(void)touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event {
if (timer != nil)
[timer invalidate];
timer = nil;
}
-(void)touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event {
if (timer != nil) {
[timer invalidate];
timer = nil;
}
}
This way, you can repeat the event at a predefined interval, and not have to rely on a button, and get the repeat behaviour you're looking for.
Note the touchesMoved trigger - if they move their finger, this cancels the timer, and the player stops moving.
hold down button after 1 second and loop the action using jQuery
As I said you need to use setTimeout()
var timeout = 0;
$('#button_add').mousedown(function () {
setTimeout(function(){
timeout = setInterval(function () {
value_of_something ++;
}, 50);
} , 1000);
return false;
});
Jsfiddle
UIButton with hold down action and release action
try this
UIButton *aButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
aButton.frame = CGRectMake(xValue, yValue, 45, 45);
[aButton addTarget:self action:@selector(holdDown) forControlEvents:UIControlEventTouchDown];
[aButton addTarget:self action:@selector(holdRelease) forControlEvents:UIControlEventTouchUpInside];
- (void)holdDown
{
NSLog(@"hold Down");
}
- (void)holdRelease
{
NSLog(@"hold release");
}
for NSPratik's case: u can use the event UIControlEventTouchUpOutside
If user long press button and after some time, instead of releasing the finger, user will move his/her finger out of the bounds of button. just add one more event.
UIButton *aButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
aButton.frame = CGRectMake(xValue, yValue, 45, 45);
[aButton addTarget:self action:@selector(holdDown) forControlEvents:UIControlEventTouchDown];
[aButton addTarget:self action:@selector(holdRelease) forControlEvents:UIControlEventTouchUpInside];
[aButton addTarget:self action:@selector(holdReleaseOutSide) forControlEvents:UIControlEventTouchUpOutside]; //add this for your case releasing the finger out side of the button's frame
//add this method along with other methods
- (void)holdReleaseOutSide
{
NSLog(@"hold release out side");
}
Swift Version
var aButton:UIButton = UIButton.buttonWithType(UIButtonType.Custom) as UIButton
aButton.frame = CGRectMake(xValue,yValue, 45, 45)
aButton.setTitle("aButton", forState: UIControlState.Normal)
aButton.backgroundColor = UIColor.greenColor()
aButton.addTarget(self, action: Selector("holdRelease:"), forControlEvents: UIControlEvents.TouchUpInside);
aButton.addTarget(self, action: Selector("HoldDown:"), forControlEvents: UIControlEvents.TouchDown)
self.addSubview(aButton)
//target functions
func HoldDown(sender:UIButton)
{
print("hold down")
}
func holdRelease(sender:UIButton)
{
print("hold release")
}
Related Topics
How to Do Weak Linking in Swift
Alamofire with a Self-Signed Certificate/Servertrustpolicy
How to Set Http Header Fields in Objective-C
Swift iOS9 New Contacts Framework - How to Retrieve Only Cncontact That Has a Valid Email Address
How to Access an Xcassets Directory on the Filesystem
Thread Error in Ibaction While Overriding Prepareforsegue Function
Xmlparser.Sharedparser.Decode() in Swift3
Uibutton Remove All Target-Actions
How to Check If a Static Library Is Built for 64-Bit
How to Position Views on Top of Each Other
How to Build Boost-Libraries for Iphone
How to Remove Border from Segmented Control
Exception Type: Exc_Crash (Sigabrt)
iOS Swift: How to Change the Font Style of a Certain Word in a String
Uiscrollview Pauses Nstimer While Scrolling
Error: "Array Index Out of Range" in Multidimensional Array
How to Get a Crash Log Due to Expiration of Provisioning Profile