UIButton Long Press Event
You can start off by creating and attaching the UILongPressGestureRecognizer
instance to the button.
UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPress:)];
[self.button addGestureRecognizer:longPress];
[longPress release];
And then implement the method that handles the gesture
- (void)longPress:(UILongPressGestureRecognizer*)gesture {
if ( gesture.state == UIGestureRecognizerStateEnded ) {
NSLog(@"Long Press");
}
}
Now this would be the basic approach. You can also set the minimum duration of the press and how much error is tolerable. And also note that the method is called few times if you after recognizing the gesture so if you want to do something at the end of it, you will have to check its state and handle it.
UIButton with single press and long press events swift
If you want to perform any action with single tap you and long press the you can add gestures into button this way:
@IBOutlet weak var btn: UIButton!
override func viewDidLoad() {
let tapGesture = UITapGestureRecognizer(target: self, #selector (tap)) //Tap function will call when user tap on button
let longGesture = UILongPressGestureRecognizer(target: self, #selector(long)) //Long function will call when user long press on button.
tapGesture.numberOfTapsRequired = 1
btn.addGestureRecognizer(tapGesture)
btn.addGestureRecognizer(longGesture)
}
@objc func tap() {
print("Tap happend")
}
@objc func long() {
print("Long press")
}
This way you can add multiple method for single button and you just need Outlet for that button for that..
Prevent UIButton Long Press Repeating Function
You should call the long
When gesture
activated. it's called one time whenever long gesture
active.
@objc func hitlongprass(_ sender : Any){
guard let longPress = sender as? UILongPressGestureRecognizer else
{ return }
if longPress.state == .began { // When gesture activated
long()
}
else if longPress.state == .changed { // gesture Calls multiple times by time changed
}
else if longPress.state == .ended { // When gesture end
}
}
func long() {
print("Long press")
}
Calling:
let longGesture = UILongPressGestureRecognizer(target: self, action: #selector(hitlongprass(_:)))
UIbutton with longpress and Touchup inside
For the tap you can use UIButton's "addTarget:..." method and for the longpress you can add a gesture recognizer:
UIButton *btn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
btn.frame = CGRectMake(100.0, 100.0, 100.0, 20.0);
[btn setTitle:@"Test" forState:UIControlStateNormal];
[btn addTarget:self action:@selector(userTapped:) forControlEvents:UIControlEventTouchUpInside];
UILongPressGestureRecognizer *gr = [[UILongPressGestureRecognizer alloc] init];
[gr addTarget:self action:@selector(userLongPressed:)];
[btn addGestureRecognizer:gr];
[gr release];
[self.view addSubview:btn];
Of course you need to implement the 2 methods that will be called:
- (void)userTapped:(id)sender {
NSLog(@"user tapped");
}
- (void)userLongPressed:(id)sender {
NSLog(@"user long pressed");
}
Hope that helps.
=========
EDIT: It seems that you are using your button as a BarButtonItem inside a UIToolbar. So I changed my code to do the same:
- (void)viewDidLoad {
[super viewDidLoad];
// set up the button
UIImage *redImage = [UIImage imageNamed:@"TabFav2.png"];
UIButton *tabRedbutton = [UIButton buttonWithType:UIButtonTypeCustom];
tabRedbutton.backgroundColor = [UIColor redColor];
[tabRedbutton setImage:redImage forState:UIControlStateNormal];
tabRedbutton.frame = CGRectMake(0.0, 0.0, 50,35);
// set up a bar button item with the button as its view
UIBarButtonItem *redTab = [[UIBarButtonItem alloc] initWithCustomView:tabRedbutton];
// set up toolbar and add the button as a bar button item
UIToolbar *toolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0.0, 100.0, 768.0, 40.0)];
toolbar.barStyle = UIBarStyleBlack;
NSArray *items = [NSArray arrayWithObject:redTab];
[toolbar setItems:items];
[self.view addSubview:toolbar];
[toolbar release];
// add tap handler to button for tap
[tabRedbutton addTarget:self action:@selector(redbottonmethod) forControlEvents:UIControlEventTouchUpInside];
// add gesture recognizer to button for longpress
UILongPressGestureRecognizer *longpressGesture1 = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPressHandler:)];
longpressGesture1.minimumPressDuration =0.1;
[tabRedbutton addGestureRecognizer:longpressGesture1];
[longpressGesture1 release];
}
And the two methods that get called:
- (void)longPressHandler:(UILongPressGestureRecognizer *)gestureRecognizer {
NSLog(@"Long press");
}
-(void)redbottonmethod {
NSLog(@"single tapped");
}
This code definitely works.
By the way: I noticed that in your code in the 2 methods that get called you have typo: You must use NSLog() and not NSlog(). Could that be the problem?
How to handle touch events and gesture events on a UIButton?
In order not to trigger both you should flag the button with a global variable or a tag, so in the target of UIControlEventTouchUpInside
you can filter the action.
So let's assume your UILongPressGestureRecognizer
calls longPress
when fires, and it's initialize in your custom cell. & UIControlEventTouchUpInside
calls the target btnPressed
UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPress:)];
[self.button addGestureRecognizer:longPress];
[self.button addTarget:self action:@selector(btnPressed:) forControlEvents:UIControlEventTouchUpInside];
Selector call, inside your custom cell:
-(void)longPress:(UIButton*)btn
{
// Flag the button,
self.button.tag = 1;
// Do LongPress stuff.
}
Target of the button for UIControlEventTouchUpInside
- (void)btnPressed:(id)sender {
UIButton *senderButton = sender;
if(senderButton.tag == 1) {
// Long press has been executed, set back the flag to 0
senderButton.tag = 0;
} else {
// Long press not executed
// Do the TouchUpInside stuff.
}
}
figure out which button was pressed while differ between long-press and tap. swift
The main issue, in this case, is both gestures will be added ONLY for the largeOption
button! To clarify, the gesture is added only for one component, which in your case, it should be added only for the latest one (which is largeOption
):
smallOption.addGestureRecognizer(tapGesture) <-- skipped
mediumOption.addGestureRecognizer(tapGesture) <-- skipped
largeOption.addGestureRecognizer(tapGesture) <-- added
smallOption.addGestureRecognizer(longGesture) <-- skipped
mediumOption.addGestureRecognizer(longGesture) <-- skipped
largeOption.addGestureRecognizer(longGesture) <-- added
Logically speaking, this might be the answer to your question:
Is it possible to find out what button was pressed in the tap and long function, or will I need to do two functions for each button?
you need to add two gestures for each button because a particular gesture can only be added to one view.
However, you don't have to declare new action methods in addition to @objc func tap(_ sender: UIGestureRecognizer)
and @objc func long(_ sender: UIGestureRecognizer)
existing ones. What you could do instead is to check the sender
's view. Example:
Let's assume that we manually added tow gestures for each button:
// gestures:
let smallOptionTapGesture = UITapGestureRecognizer(target: self, action: #selector(tap))
let smallOptionLongGesture = UILongPressGestureRecognizer(target: self, action: #selector(long))
smallOptionLongGesture.minimumPressDuration = 0.5
let mediumOptionTapGesture = UITapGestureRecognizer(target: self, action: #selector(tap))
let mediumOptionLongGesture = UILongPressGestureRecognizer(target: self, action: #selector(long))
mediumOptionLongGesture.minimumPressDuration = 0.5
let largeOptionTapGesture = UITapGestureRecognizer(target: self, action: #selector(tap))
let largeOptionLongGesture = UILongPressGestureRecognizer(target: self, action: #selector(long))
largeOptionLongGesture.minimumPressDuration = 0.5
// adding them:
smallOption.addGestureRecognizer(smallOptionTapGesture)
mediumOption.addGestureRecognizer(mediumOptionTapGesture)
largeOption.addGestureRecognizer(largeOptionTapGesture)
smallOption.addGestureRecognizer(smallOptionLongGesture)
mediumOption.addGestureRecognizer(mediumOptionLongGesture)
largeOption.addGestureRecognizer(largeOptionLongGesture)
Therefore, what you could do is:
@objc func tap(_ sender: UIGestureRecognizer) {
// an example of how you could check the button
if sender.view == smallOption {
print("small short-press")
} else if sender.view == mediumOption {
print("medium short-press")
} else if sender.view == largeOption {
print("large short-press")
}
}
@objc func long(_ sender: UIGestureRecognizer) {
// you could apply the same above approach here
}
The other option is to create action methods for each button separately.
Related Topics
Facebooksdk(4.1.X) Custom Login UI Button - Swift(1.2)
Building Ffmpeg iOS Libraries for Armv7, Armv7S, Arm64, I386 and Universal
Ignore Manual Entries from Apple Health App as Data Source
Using Sysctlbyname() from Swift
Where Does a Swift iOS Application Begin Its Life
Nsdateformatter Datefromstring Always Returns Nil
Aws Cognito iOS Developer Authenticated Identities
How to Automatically Convert Manual Retain-Release Code to Arc
Seed and Maintain Cloudkit Public Database Without Requiring Icloud Login
Asynchronous Upload with Nsurlsession Will Not Work But Synchronous Nsurlconnection Does
Why Does Unexpected Non-Void Return Value in Void Function Happen
iOS Client Certificates and Mobile Device Management
Document Directory Path Change When Rebuild Application
Remote Image Size Without Downloading
How to Properly Remove Node When Out of Screen Bounds