is Gesture Recognization working on buttons or not? - iphone

In my app, I wrote these lines of code :
- (void)viewDidLoad {
[super viewDidLoad];
UITapGestureRecognizer *tapper = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapped:)];
[mybutton1 addGestureRecognizer:tapper];
[mybutton2 addGestureRecognizer:tapper];
[mybutton3 addGestureRecognizer:tapper];
[tapper release];
}
-(void)tapped:(UIGestureRecognizer *)sender{
NSLog(#"I'am in tapped");
}
but nothing happened. why ? and if I need to get the button's currentTitle inside tapped, can I ?
Thanks

You're missing the recognizer delegate. Implement that. You should also add the UIGestureRecognizerDelegate protocol to your header file and make recognizer.delegate = self.
re: getting the title - you can get the title. in your tap event handler you can extract that information from the sender object. i'll post some code later...

You don't need to use a gesture recogniser just to detect when a button is pressed. A button knows when it's being pressed!
Try:
{
// Blah...
[myButton addTarget:self action:#selector(tapped:) forControlEvents:UIControlEventTouchUpInside];
// Other stuff
}
-(void)tapped:(id)sender {
NSLog (#"I'm in tapped!");
}

A gesture recognizer can only be attached to one view at a time. Handling single taps on buttons can just as easily be done using IBAction. You can create one IBAction and connect all three buttons to it.
- (IBAction)tapped:(id)sender {
UIButton *button = (UIButton *)sender;
NSLog(#"%#", button.titleLabel.text);
}
A similar question: UITapGestureRecognizer on a UIButton

Related

iPhone sdk Tool Tip

Can i show a Tool tip like this:
Also, I want to show this tool tip when that area is pressed and HOLD. Is there a handler for this gesture?
You can do that in didSelectRowAtIndex method of TableViewController delegate method.
Look here. It is best implementation to have Popover controllers in iPhone. Download run and integrate into your code and change according to your requirement.
In addition to what #jennis said, there is indeed a way to capture long hold gestures you could use UILongPressGestureRecognizer
like this
UILongPressGestureRecognizer *gesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(longHold)];
[cell addGestureRecognizer:gesture];
and longHold method
- (void) longHold
{
//Cell has recieved gesture
}
It works, I agree with Omar Abdelhafith
-(void)viewWillAppear:(BOOL)animated
{ //gesture declared in .h file
gesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(longHold)];
[your view addGestureRecognizer:gesture];
}
-(void)longHlod
{
//do whatever you want
}

UILongPressGestureRecognizer stop handle without stop touching

I'm using UILongPressGestureRecognizer class to handle if one item is being selected.
The logic is as follows: User press during 1 second an item (UIView subclass). Once the gesture is detected, the item is highlighted and moveable.
The user must move this item across the screen without stop touching it.
The problem I'm facing is the gesture recognized shadows touchesBegan/Move/Ended necessary for the item class to arrange the movement.
I tried to remove the gesture recognized once is detected and the item selected. But still sending messages to the handle of gesture instead of call touches methods.
Anyone knows any way to stop "listening" the gesture recognizer without leave the finger of the screen?
Thanks.
Here the code:
-(void)addGestures
{
UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc]
initWithTarget:self
action:#selector(handleLongPress:)];
longPress.minimumPressDuration = iItemLongPressTime;
[self addGestureRecognizer:longPress];
[longPress release];
}
- (void)handleLongPress:(UILongPressGestureRecognizer*)sender {
if (sender.state == UIGestureRecognizerStateEnded) {
NSLog(#"Long press Ended");
}
else {
if (self.isSelected) return;
if ([delegate respondsToSelector:#selector(singleTouch:)])
[delegate singleTouch:self];
[self removeGestureRecognizer:[self.gestureRecognizers objectAtIndex:0]];
NSLog(#"Long press detected.");
}
}
As you can see in the else branch the delegate calls enables all procedures to mark this item as selected, and just after remove the recognizers.
What I'm missing?
--EDIT--
Done! This works:
#pragma mark Gesture Functions
-(void)addGestures
{
UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc]
initWithTarget:self
action:#selector(handleLongPress:)];
longPress.minimumPressDuration = iItemLongPressTime;
[self addGestureRecognizer:longPress];
[longPress release];
}
- (void)handleLongPress:(UILongPressGestureRecognizer*)sender {
if (sender.state == UIGestureRecognizerStateEnded) {
NSLog(#"Long press Ended");
}
else {
NSLog(#"Long press detected.");
if (self.isSelected) return;
if ([delegate respondsToSelector:#selector(singleTouch:)])
[delegate singleTouch:self];
[sender removeTarget:self action:#selector(handleLongPress:)];
sender.enabled = NO;
[self removeGestureRecognizer:sender];
}
}
Regards!
Does the custom UIView class have its own touch handling code? If not, a simple solution is to set the allowableMovement property of the UILongPressGestureRecognizer to CGFLOAT_MAX, or some big number, and use the gesture update callbacks to drag your custom view around. You can get the displacement using the - (CGPoint)locationInView:(UIView *)view method on the superview, and compare its position to when the recognizer began.
There are two solutions in my mind.
For animating uiview, please wrote a new class which is inherited from the UIView class and implement the touch delegates instead of writing the Gustures to handle animation(if the touch delegates are not triggering in the current class).
2.I have successfully removed the UILongPressGestureRecognizer after triggered it once.
Please refer the below code .ask me if you have any queries
Steps I have Done
I have added a UIView as "myView" to my main-view when main-view loads.
I have given the Tag to the myView (you can give 1,2,3…etc) to differentiate the tapped view from the main-view subviews.
Assigned the UILongPressGestureRecognizer gesture to myView and assigned target as "moveMe" method.
When user Pressed the myView long, the "moveMe" method will trigger.
Then I iterated the mainView Subviews with the condition Tag == 1
I have removed the UILongPressGestureRecognizer from the subview.As we can know that Tagged 1 main-view subView is myView.
So the NSLog(#"gesture removed"); and NSLog(#"moveMe"); will log in console only at one time.
The NSLog(#"touchesBegan"); will trigger first instead of triggering the "moveMe" method.
Then NSLog(#"touchesBegan"); will trigger always after removed the gesture . "moveMe" method will not trigger ever.
Code
- (void)viewDidLoad {
//Adding to UIView to main view when application is loading.
UIView *myView = [[UIView alloc] initWithFrame:CGRectMake(20, 20, 80, 80)];
myView.backgroundColor = [UIColor viewFlipsideBackgroundColor];
myView.tag = 1; //adding a tag to identify it.
//Adding Long Press Gesture to the UIView.
UILongPressGestureRecognizer *myGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(moveMe:)];
[myView addGestureRecognizer:myGesture];
[myGesture release];
myGesture = nil;
[self.view addSubview:myView];
[myView release];
myView = nil;
[super viewDidLoad];
}
//Method to trigger when user pressed long on the added UIView.
-(void)moveMe:(id)sender
{
for (UIView *subViews in [self.view subviews])
{
if (subViews.tag == 1) {
[subViews removeGestureRecognizer:sender];
NSLog(#"gesture removed");
}
}
NSLog(#"moveMe");
}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
NSLog(#"touchesBegan");
}
or please refer Disable gesture recognizer iOS

Hide UIPopoverController with double tap

I've got splite-view application and of course there is a popover controller in the vertical DetailView, how can I hide with double-tap? thanks
You have to add a doubleTap gesture recognizer and call dismissPopoverAnimated:
First declare a gesture recognizer and configure it to your view:
UITapGestureRecognizer * doubleTapGesture = [[UIGestureRecognizer alloc] initWithTarget:self action:#selector(doubleTapCallback:)];
doubleTapGesture.numberOfTapsRequired = 2;
[yourView addGestureRecognizer:doubleTapGesture];
[doubleTapGesture release];
Then implement the callback:
- (IBAction) doubleTapCallback: (UITapGestureRecognizer *) sender
{
[yourPopOverController dismissPopoverAnimated:YES]
}

Implement Long press on button and show delete button on top of that button like deleting app from background

I want to implement a long press on my button and after that long press a cross button should appear on the top of the button to remove that button from scroll view which is added in table view.
I search on web and got UILongPressGestureRecognizer to implement.I tried with it but I have many button in my scroll view and I put UILongPressGestureRecognizer on every button but how will I give reference of the pressed button to the selector method so that I can add a cross button on that particular pressed button.
UILongPressGestureRecognizer *longPressGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(deleteAppFromList:)];
UIButton *btn=(UIButton *)[cell.contentView viewWithTag:101+i];
[btn addGestureRecognizer:longPressGesture];
[longPressGesture release];
Please suggest me how to implement this.I want to do the functionality just as when we delete an app from ios device or simulator.
I've just done something similar. I detect the touchDown event, schedule a timed method which sets a flag after 1 second, then when the touch up event is detected it checks the flag and calls the appropriate method.
[myButton addTarget:self action:#selector(itemTouchDown) forControlEvents:UIControlEventTouchDown];
[myButton addTarget:self action:#selector(itemTouchUpInside) forControlEvents:UIControlEventTouchUpInside];
-(void)itemHoldTimer:(NSTimer *)timer
{
self.itemHoldTimer = nil;
didHold = YES;
}
-(void)itemTouchDown{
didHold = NO;
self.itemHoldTimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:#selector(itemHoldTimer:) userInfo:nil repeats:NO];
}
-(void)itemTouchUpInside {
if (didHold) {
didHold = NO;
[self itemWasTouchedUpAndDidHold];
} else {
didHold = NO;
[self itemWasTouchedUp];
}
}
In your handler method that you set up as the target of the gesture recognizer you are passed a reference to the recognizer that fired, e.g.:
- (void)handleGesture:(UIGestureRecognizer *)gestureRecognizer;
The recognizer has a 'view' property, which is the view the recognizer is attached to. Use this directly or get the tag of this view and you can work out which button was pressed.
UIView *myButton = gestureRecognizer.view;
Having said that, adding a gesture recognizer to each button seems the wrong way to do this. I would create a custom control and handle 'touchesBegan' and 'touchesEnded' directly.
In the handler method of the long press recognizer, use the view property and its tag to identify the view.
-(void)handleLongPress:(UILongPressGestureRecognizer*)longPressRecognizer
{
//longPressRecognizer.view.tag
}

how can i detect touch on already selected UIBarButtonItem?

how can i detect touch on already selected UIBarButtonItem?
if i touch UIBarButtonItem , it will be selected..but if i touch the same again,
how can i identify it ? any help please?
the code is as follows.. initWithCustomView:sortToggle in which sortToggle is segmented control...
UIBarButtonItem *sortToggleButtonItem = [[UIBarButtonItem alloc]
initWithCustomView:sortToggle];
[sortToggle release];
UIBarButtonItem *flexibleSpaceButtonItem = [[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace
target:nil
action:nil];
NSArray *buttonArray = [NSArrayarrayWithObjects:flexibleSpaceButtonItem,
sortToggleButtonItem,
flexibleSpaceButtonItem, nil];
[self setToolbarItems: buttonArray animated:YES];
The UIBarButtonItem does not inherit from the UIResponder so you can not get touchesBegan / touchedEnded etc events directly. If you set the UISegmentedControl to be momentary (yourSegControl.momentary = YES) you can select a button more than once. Is this helpful for your situation?
Otherwise, you should probably subclass the UISegmentedControl (which inherits from the UIResponder) and handle the extra touches yourself (don't forget to call super in any touch method you override).
I needed to be able to detect when the user selected an already selected index, and I found the problem was that the UISegmentedControl only fired the UIControlEventValueChanged event. I wanted to be able to get the UIControlEventTouchUpInside event so I could do something.
The solution is to subclass UISegmentedControl and overwrite the touch event to fire the event you want.
Create a subclass of UISegmentedControl and override touchesBegan:withEvent:...
/* MySegmentedControl.m, a subclass of UISegmentedControl... */
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
//dont forget to call super!
[super touchesBegan:touches withEvent:event];
//fire the event we want to listen to
[self sendActionsForControlEvents:UIControlEventTouchUpInside];
}
Then listen for the UIControlEventTouchUpInside of your segmented control instead of UIControlEventValueChanged so that you only get one event fired...otherwise it will fire the UIControlEventValueChanged event once naturally, and once when you fire it, and you'll get two events (which you obviously don't want).
[mySegmentedControlInstance addTarget:self action:#selector(mySegmentedControlSelected:) forControlEvents:UIControlEventTouchUpInside]
This way you get an event once every time the control is touched, not just when it's value is changed.