How to Recognize a Hold Button {iPhone SDK} - iphone

Hi i have a Button i want hold this button to write something but i don't know how can i recognize hold button , can you help me ? thank you

TouchDownInside event triggered, start a NStimer.
TouchUpInside event triggered, cancel the timer.
Make the timer call your method to execute if the user holds the button : the timer delay will be the amount of time required to recognize hold.

You can also use UILongPressGestureRecognizer.
In your initialization method (e.g. viewDidLoad), create a gesture recognizer and attach it to your button:
UILongPressGestureRecognizer *gesture = [[UILongPressGestureRecognizer alloc]
initWithTarget:self
action:#selector(myButtonLongPressed:)];
// you can control how many seconds before the gesture is recognized
gesture.minimumPressDuration = 2;
// attach the gesture to your button
[myButton addGestureRecognizer:gesture];
[gesture release];
The event handler myButtonLongPressed: should look like this:
- (void) myButtonLongPressed:(UILongPressGestureRecognizer *)gesture
{
// Button was long pressed, do something
}
Note that UILongPressGestureRecognizer is a continuous event recognizer.
While the user is still holding down the button, myButtonLongPressed: will be called multiple times.
If you just want to handle the first call, you can check the state in myButtonLongPressed::
if (gesture.state == UIGestureRecognizerStateBegan) {
// Button was long pressed, do something
}

Related

activate ccTouchesBegan with a button in cocos2d and make it work just one time

I want to make something happen with ccTouchesBegan but i want to restrict that action to a button, meaning that the action by the button should trigger ccTouchesBegan but only one time. After the code inside ccTouchesBegan has finished, the interface should go back to normal and wait for the button to be pressed to trigger the action again.
I have made the button trigger ccTouchesBegan when its pressed but the problem is that once the button is pressed, the code inside ccTouchesBegan keeps working and doing the same thing from then on when a touch action on the simulator is done.
This is the code that i have so far.
this is a flag method that i have created so that i know the button has been pressed and i can control the actions on ccTouchesBegan.
- (void) selector{
click = true;
}
this is the button which calls the method selector.
- (void) button{
CCMenuItemImage *touchesMovedButton = [CCMenuItemImage itemFromNormalImage:#"ActionButton-Normal.png"
selectedImage:#"ActionButton-Selected.png"
target:self
selector:#selector(selector)
];
CCMenu *selectorButton = [CCMenu menuWithItems: touchesMovedButton, nil];
selectorButton.position = ccp(64, 64);
[self addChild: selectorButton];
}
and this is the method ccTouchesBegan
- (void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
//this part doesn't let the interface start the ccTouchesBegan code until the button has been pressed.
if (click == false) {
return;
}
// the else code starts when the button has been pressed.
else{
CCLOG(#"you have touched the interface!!");
}
}
That's the code, the interface doesn't do any action until the button is pressed but after it's pressed it keeps printing the CCLOG each time i touch the interface. i just want it to do it once and then when i press the button again it should do it just one time again.
does anyone know how to do this? or maybe point out my mistake?
You simply have the logical mistake. Use the Code below in the ccTouchesBegan It would work perfectly as you need...
if (click == false)
{
return;
}
// the else code starts when the button has been pressed.
else if(click == true)
{
CCLOG(#"you have touched the interface!!");
click=false; // You need to make false if you want to make touch single time enabled
}

button should fire the action until I keep the button down

I have UIscrollview in which I have placed images.I use the buttons(touch down) to move the position of the images by 5pixels inside the scroll view…..Button fires the action only if I repeatedly touches the buttons ( it moves the images to 5pixels if I touches the button again and again) I want my button to fire the action until I keep the button down (it should moves the images until I release the button)…
Is there any possibility to scroll the UIscrollview by means of button click?
You'll have to listen to the TouchDown and TouchUp events. When a TouchDown event is fired you start a timer (or other) that periodically calls a method, and when you receive a TouchUp event you stop it.
It might looks something like that:
-(IBAction)touchDownAction:(id)sender
{
self.yourtimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:#selector(aselector) userInfo:nil repeats:YES];
}
-(IBAction)touchUpAction:(id)sender
{
if ([yourtimer isValid])
{
[yourtimer invalidate];
}
}
(You just have to link your button with these methods via IB)

filtering single and double taps

When the user single taps my view, i need one specific method to run.
When the user double taps, i need another method do take place.
The problem is that the double tap triggers the single tap, and it introduce bugs in my logic.
I can't use UIGestureRecognizer because i need to keep track of the points.
I try some booleans, but no chance. I also tried the cancel/perfomSelector-delay technique, but it does not work (that's strange because other folks on other forums said it works, maybe the simulator touch detection is different ?)
I'm trying to let the user set the position (drag, rotate) of a board piece, but i need to be aware of piece intersections, clip to the board area, etc, that's why a simple boolean will not solve the problem.
Thanks in advance!
Check this, seems right what you are looking for:
Below the code to use UITapGestureRecognizer to handle single tap and double tap. The code is designed that it won't fire single tap event if we got double tap event. The trick is use requireGestureRecognizerToFail to ask the single tap gesture wait for double tap event failed before it fire. So when the user tap on the screen, the single tap gesture recognizer will not fire the event until the double tap gesture recognizer. If the double tap gesture recognizer recognize the event, it will fire a double tab event and skip the single tap event, otherwise it will fire a single tap event.
UITapGestureRecognizer *doubleTapGestureRecognizer = [[UITapGestureRecognizer alloc]
initWithTarget:self action:#selector(handleDoubleTap:)];
doubleTapGestureRecognizer.numberOfTapsRequired = 2;
//tapGestureRecognizer.delegate = self;
[self addGestureRecognizer:doubleTapGestureRecognizer];
//
UITapGestureRecognizer *singleTapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleSingleTap:)];
singleTapGestureRecognizer.numberOfTapsRequired = 1;
[singleTapGestureRecognizer requireGestureRecognizerToFail: doubleTapGestureRecognizer];
//tapGestureRecognizer.delegate = self;
[self addGestureRecognizer:singleTapGestureRecognizer];
Possibly I don't understand exactly what you mean by "i need to keep track of the points", but I don't see any problems with doing this with a gesture recognizer.
Swift 3 Solution:
doubleTap = UITapGestureRecognizer(target: self, action:#selector(self.doubleTapAction(_:)))
doubleTap.numberOfTapsRequired = 2
singleTap = UITapGestureRecognizer(target: self, action:#selector(self.singleTapAction(_:)))
singleTap.numberOfTapsRequired = 1
singleTap.require(toFail: doubleTap)
self.view.addGestureRecognizer(doubletap)
self.view.addGestureRecognizer(singleTap)
In the code line singleTap.require(toFail: doubleTap) we are forcing the single tap to wait and ensure that the tap even is not a double tap. Which means we are asking to ensure the double tap event has failed hence it is concluded as a single tap.
Swift Solution :
doubleTapSmall1.numberOfTapsRequired = 2
doubleTapSmall1.addTarget(self, action: "doubleTapPic1")
smallProfilePic1.addGestureRecognizer(doubleTapSmall1)
singleTapSmall1.numberOfTapsRequired = 1
singleTapSmall1.addTarget(self, action: "singleTapPic1")
singleTapSmall1.requireGestureRecognizerToFail(doubleTapSmall1)
smallProfilePic1.addGestureRecognizer(singleTapSmall1)
Just implement the UIGestureRecognizer delegate methods by setting the delegate properly.
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch{
return YES;
}
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{
return YES;
}
Also add this line of code
[singleTap requireGestureRecognizerToFail:doubleTap];

iphone button pressed for 3 seconds goes to a different view

I have a button in my app that when pressed goes to a view
but I need that when pressed for 3 seconds it would go to a different view,
like when you are on ipad on safari and you keep pressed the url, and it shows a pop up with copy etc,
but I need that when pressed for 3 second it goes to another view...
hope this makes sense, I will explain better if not understood,
thank you so much!
pd, also how to make it show the pop up style window?
cheers!
Try setting an NSTimer property in your view controller. When the button's pressed, create the timer and assign it to your property. You can detect that moment with this:
[button addTarget:self action:#selector(startHoldTimer) forControlEvents:UIControlEventTouchDown];
and assign with this:
-(void) startHoldTimer {
self.myTimer = [NSTimer scheduledTimerWithTimeInterval:3.0 target:self selector:#selector(goToNewView:) userInfo:nil repeats:NO];
}
Then set an action to run on a canceled touch, or a touch up inside:
[button addTarget:self action:#selector(touchUp) forControlEvents:UIControlEventTouchUpInside];
[button addTarget:self action:#selector(cancelTimer) forControlEvents:UIControlEventTouchCancel];
and
//if timer fires, this method gets called
-(void) goToNewView {
[self cancelTimer];
[self loadSecondView];
}
// normal button press invalidates the timer, and loads the first view
-(void) touchUp {
[self cancelTimer];
[self loadFirstView];
}
//protected, just in case self.myTimer wasn't assigned
-(void) cancelTimer {
if (self.myTimer != nil)
if ([self.myTimer isValid]) {
[self.myTimer invalidate];
}
}
That should take care of it!
Use a UILongPressGestureRecognizer, added to the button with -addGestureRecognizer:—it'll handle timing the touch and fire an event when it recognizes that the button's been held down for a while. You might want to reconsider your interaction pattern, though—generally, things that can be long-pressed aren't buttons, they're actual pieces of data in a view, like an image or a link in Safari.
One possible approach would be to implement one of the touches events (I don't remember the name, but the method that fires when you touch down on the button), and schedule a timer to fire in three seconds. If the user lifts her finger before that time, cancel the timer and perform the normal button click. If the time does fire (i.e. 3 seconds have elapsed), ignore the touch up event and load your new view.

detecting long tap on iPhone

I am working on an iPhone app which requires me to check if the button has been tapped & held pressed for 6 seconds & then fire an action which is playing some sort of sound.
How should I detect this 6 second tap?
On the other hand the user can also keep on tapping button for 6 seconds & then the same action should fire.
What should I do with multiple taps, how would I know that all the taps fall under the 6 second bracket?
For a six second long press, use a UILongPressGestureRecognizer with its minimumPressDuration property set to 6.
Write your own gesture recognizer (say, LongTappingGestureRecognizer) for continuous tapping for a given period; it shouldn't be too tricky. Give it a property like UILongPressGestureRecognizer's minimumPressDuration (say, minimumTappingDuration) and a property (say, maximumLiftTime) that determines how long a finger can be lifted off before it's not considered to be a long tapping gesture.
When it first receives touchesBegan:withEvent:, record the time.
When it receives touchesEnded:withEvent:, start an NSTimer (the lift timer) that sends the gesture recognizer a cancel message (e.g. cancelRecognition) after maximumLiftTime.
When it receives touchesBegan:withEvent: when there's a start time, cancel the lift timer (if any).
The cancelRecognition will transition to the failed state.
There are various strategies for handling recognizing when the end of the gesture is reached, after minimumTappingDuration. One is to check in both the touchesBegan:withEvent: and touchesEnded:withEvent: handlers if the difference between the current time and the start time is >= minimumTappingDuration. The problem with this is that it will take longer than minimumTappingDuration to recognize the gesture if the user is tapping slowly and hir finger is down when the minimumTappingDuration is reached. Another approach is to start another NSTimer (the recognition timer) when the first touchesBegan:withEvent: is received, one that will cause transition to the recognized state and that is cancelled in cancelRecognition. The tricky thing here is what to do if the finger is lifted when the timer fires. The best approach might be a combination of the two, ignoring the recognition timer if the finger is lifted.
There's more to the details, but that's the gist. Basically, it's a long press recognizer that lets the user lift hir finger off the screen for brief periods. You could potentially use just the tapping recognizer and skip the long press recognizer.
I realize this is quite dated question, however answer should be pretty simple.
In your View controller viewDidLoad:
//create long press gesture recognizer(gestureHandler will be triggered after gesture is detected)
UILongPressGestureRecognizer* longPressGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(gestureHandler:)];
//adjust time interval(floating value CFTimeInterval in seconds)
[longPressGesture setMinimumPressDuration:6.0];
//add gesture to view you want to listen for it(note that if you want whole view to "listen" for gestures you should add gesture to self.view instead)
[self.m_pTable addGestureRecognizer:longPressGesture];
[longPressGesture release];
Then in your gestureHandler:
-(void)gestureHandler:(UISwipeGestureRecognizer *)gesture
{
if(UIGestureRecognizerStateBegan == gesture.state)
{//your code here
/*uncomment this to get which exact row was long pressed
CGPoint location = [gesture locationInView:self.m_pTable];
NSIndexPath *swipedIndexPath = [self.m_pTable indexPathForRowAtPoint:location];*/
}
}
Here is my solution.
- (IBAction) micButtonTouchedDownAction {
self.micButtonTimer = [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:#selector(micButtonAction:) userInfo:nil repeats:YES];
self.micButtonReleased = FALSE;
}
- (IBAction) micButtonTouchedUpInsideAction {
self.micButtonReleased = TRUE;
}
- (IBAction) micButtonTouchedUpOutsideAction {
self.micButtonReleased = TRUE;
}
- (void) micButtonAction:(NSTimer *)timer {
[self.micButtonTimer invalidate];
self.micButtonTimer = nil;
if(self.micButtonReleased) {
NSLog(#"Tapped");
}
else {
NSLog(#"Touched");
}
}