UIButton long press with finger stationary - iphone

In my project I have the need to use a UIButton (or another component) to handle events using long press.
Let me explain, I should make that mind I hold down the button a timer to count the seconds and release to pressure stop, I tried with the management of UILongPressGestureRecognizer but is not the case because I recall the event when the button is held down but only if I move my finger, but I wish the timer went away and counted all the time in which the button is held down (with your finger stationary) and stopped counting when the finger is released.
Does anyone know how to help me?
Thanks

Use these two methods for buttons events. touchDown is called when you press the button and touchUp will be called when you lift your finger from the button. Calculate the time difference between these two methods. Also you can start timer in touchDown and stop/restart it in touchUp.
//connect this action with Touch up inside
- (IBAction)touchUp:(id)sender {
NSLog(#"up");
}
//connect this to tocuh down
- (IBAction)touchDown:(id)sender{
NSLog(#"down");
}
Updated
In coding you can write like this
[btn addTarget:self action:#selector(touchUp:) forControlEvents:UIControlEventTouchUpInside];
[btn addTarget:self action:#selector(touchDown:) forControlEvents:UIControlEventTouchDown];
and in xib

The same I have done...As u said about UILongPressGestureRecognizer, I can't understand it..but u can write ur code inside-(void)handleLongPress:(UILongPressGestureRecognizer *)gestureRecognizer
{
}. I have done same by using this method and got successful result..:). You even don't need to add timer,instead u can use...
UILongPressGestureRecognizer *lpgr = [[UILongPressGestureRecognizer alloc]
initWithTarget:self action:#selector(handleLongPress:)];
lpgr.minimumPressDuration = 1.0;
lpgr.delegate = self;
I think this works perfectly..

Related

iOS 5 UIButtons in UIScrollView not clickable

I've got a strange bug whereby two UIButtons inside a UIView, which is in turn inside a UIScrollView view are not clickable on iOS 5, but work perfectly fine on iOS 6 (screenshot shows scroller and map underneath)
The only other detail is the scroller view 'slides up' to reveal buttons when a station is selected. I've tried selecting the buttons on iOS 5, and they do get hit (visually), but the event isn't fired.
Edit: If I tap and hold on the button in the simulator, then move the cursor up the screen and release (e.g. to the part of the UIView that was always visible), the event fires.
The scroll view itself has the following settings, the latter two have only been added in order to try and make the buttons work on iOS 5 (tried various combinations):
self.scrollView.clipsToBounds = YES;
self.scrollView.scrollEnabled = YES;
self.scrollView.pagingEnabled = YES;
self.scrollView.delaysContentTouches = NO;
self.scrollView.canCancelContentTouches = NO;
The button events are all wired up correctly, with suitable targets etc:
[_updatePriceButton addTarget:self action:#selector(showPriceUpdateBoxWithPrice:) forControlEvents:UIControlEventTouchUpInside];
[_stationDetailsButton addTarget:self action:#selector(stationDetailsSelected:) forControlEvents:UIControlEventTouchUpInside];
And handlers (here's one as a sample):
- (void)stationDetailsSelected:(id)sender {
if ([self.delegate respondsToSelector:#selector(stationDetailsSelected:)]) {
[self.delegate stationDetailsSelected:_station];
}
}
Any help would be great!
Found the culprit - a misconfigured UITapGestureRecognizer on the UIView the UIButtons sit on:
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(stationInfoViewTapped:)];
[infoController.view addGestureRecognizer:tap];
Simply adding the following after init of 'tap' solves the issue in iOS 5:
[tap setCancelsTouchesInView:NO];

UIButton touchUpInside event not firing correctly

I have a tableview that contains a row with a custom cell that contains a UIButton. However, the button doesn't always fire the action. Here's my code:
submitButton = [[UIButton alloc] init];
[[submitButton layer] setBorderColor:[[UIColor whiteColor] CGColor]];
[submitButton setClipsToBounds: YES];
submitButton.backgroundColor = [UIColor grayColor];
[submitButton setTitle:#"Send" forState:UIControlStateNormal];
[self.contentView addSubview:submitButton];
[submitButton addTarget:self action:#selector(buttonAction) forControlEvents:UIControlEventTouchUpInside];
[submitButton release];
This is called in the custom cell's -(id)initWithStyle:
The buttonAction method looks like this:
-(void)buttonAction
{
NSLog(#"Button Clicked!");
}
It seems that the only way I can get the buttonAction to fire is if I press down on the button and release somewhere inside the cell's frame, but not inside the button itself. Why would that be?
*UPDATE*
Problem still exists, but I found that the more consistent way to get the button to fire is to click and drag to the left or right and then let go, as long as I let go within the bounds of the cell/row.
UPDATE #2
It looks like if I use iOS 6.0, it works as intended. But on 5.0 or 5.1 it does not.
Try assigning the same method call to TouchUpOutside as well - you should then see it work every time. TouchUpInside is only fired if you lift your finger while still within the bounds of the button.
Try [submitButton sizeToFit]. I'm wondering whether your button has any size (since I don't see you giving it any).
Also: Create your button with [UIButton buttonWithType: UIButtonTypeCustom] instead of alloc-init.

adding extra image when the UIButton remain pressed

I want to add an extra image when my button remains pressed.
Is it possible in iphone?
I guess you mean when the user makes a long press on the cell (tap down and keep finger down)?
You can add a UILongPressGestureRecognizer element to your button and specify its target and action like this:
UILongPressGestureRecognizer *longPressRecognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(longPress:)];
[self.button addGestureRecognizer:longPressRecognizer];
[longPressRecognizer release];
This will call the -longPress: method when a user long presses on the button. The callback function could look like this:
- (void)longPress:(UILongPressGestureRecognizer *)recognizer{
if (recognizer.state == UIGestureRecognizerStateBegan){
// do something like add an image
}
}
Hope this helps!
Of course Yes,
First take a custom button and set any image to it.
Then bind the following method wih Touch Down event of the button.
-(IBAction)buttonTouchedImage:(id)sender
{
[yourButton setImage:[UIImage imageNamed:#"selected.png"] forState:UIControlStateHighlighted];
}
Set button highlighted image and make it highlighted = YES when button pressed. This should work I guess.

'Hold' UIButton Behaviour - `Touch Cancelled` Control State blocking further control states

I have a button on a subview view (for talk sake the subview is a red square) that when the user holds down on the button the red square animates translucent.
I have the button connected to this method:
-(IBAction)peekToggle:(id)sendr{
NSLog(#"TOGGLE");
if(self.view.alpha ==1)self.view.alpha = 0.1;
else self.view.alpha = 1;
}
Via the behaviours: touch up inside, touch up outside and touch down. so when i hold the button down the red box goes transluscent and when i release my finger it returns to opaque.
This initially works fine, however if i hold the button down for more than 1 second, the button does not register the touch up (release of the finger).
NB:I do have a longPressGestureRecogniser on the parent view (parent of subview not parent of Button) but its not being fired (expected).
Im pretty sure my long press on the button being registered as a touch cancel and then invalidating the touch up event.
How can I prevent/work around this?
Can I Stop the touch Cancel Firing? (this event seems to fire even if i havant registered the control state) or in the touch Cancel event, tell the button to keep/start registering events?
SOLUTION:
Removed the IBActions completely and added UILongPressGestureRecognizer to the button with a very short min duration.
UILongPressGestureRecognizer * recognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(handleGesture:)];
recognizer.minimumPressDuration = 0.1;
[self.peekButton.view addGestureRecognizer:recognizer];
[recognizer release];
Then in the selector for the gr, read the gr's state:
- (void)handleGesture:(UIGestureRecognizer *)gestureRecognizer{
//1 = start
if(gestureRecognizer.state==1 || gestureRecognizer.state==3)[self peekToggle];
//3=end
}
If you think that's your problem, you can try overriding - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
and see if you get any activity there.
You can use the UIGestureRecognizerDelegate interface to fine-tune when your gesture recognizer gets fired.

Trouble using UILongPressGestureRecognizer in custom MKAnnotationView

Having trouble with a UILongPressGestureRecognizer in a custom subclass of MKAnnotationView. The callback is fired only intermittently. If I make the minimumPressDuration shorter, it fires more frequently. With a minimumPressDuration value of 0.1, it fires every time. With a value of 0.4, it never fires at all, no matter how long I leave my finger on it. At 0.2 it is hit or miss.
If I use a Tap gesture (as below), it works fine. I'm using LongPress gestures on other views and they work fine. It's just on the MKAnnotationView that I have this problem, so I'm wondering if some of the other internal event callbacks on AnnotationViews are interfering (callout, etc).
I see this problem on iOS4 (sim and phone) and 3.2 (sim, don't have a device).
Here is how I'm creating the gesture recognizer:
#define USE_LONG_PRESS 1
#define USE_TAP 0
#if USE_LONG_PRESS
UILongPressGestureRecognizer *longPressGR =
[[UILongPressGestureRecognizer alloc] initWithTarget:self
action:#selector(handleLongPress:)];
longPressGR.minimumPressDuration = 0.2;
[self addGestureRecognizer:longPressGR];
[longPressGR release];
#endif
#if USE_TAP
UITapGestureRecognizer *tapGR =
[[UITapGestureRecognizer alloc] initWithTarget:self
action:#selector(handleTap:)];
[self addGestureRecognizer:tapGR];
[tapGR release];
#endif
And the callback methods are defined in this class as follows:
- (void)handleLongPress:(UIGestureRecognizer *)gestureRecognizer {
NSLog(#"LONG PRESS");
}
- (void)handleTap:(UIGestureRecognizer *)gestureRecognizer {
NSLog(#"TAP");
}
Any iPhone gurus have any idea why this might be happening?
As far as I know the markers in 3.2 and iOS 4 already have a long press gesture attached to them to handle marker dragging. Could it be that that's interfering with your long press gesture recognizer? Maybe that's why a shorter duration works; it catches the gesture before the built in long press recognizer can.
this is just a guess *