Uibutton with Single Press and Long Press Events Swift

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



Leave a reply



Submit