As the title of this question said, I need to create a view where it needs to have action when one tap it or hold it. That means I have to add UITapGestureRecognizer and a UILongPressGestureRecognizer. I have already tried it. Somehow it redirect me to the screen where I needed to go, but it has affected it's back button. Affected by in the sense of it goes back to default text which is "Item" and it cannot perform it's assigned action.
Yes you can add these two gestures in one view. See the below code
UITapGestureRecognizer *singleTapRecognizer = [[UITapGestureRecognizer alloc]initWithTarget:self action:#selector(didTap:)];
singleTapRecognizer.numberOfTapsRequired = 1;
singleTapRecognizer.delegate = self;
[self.view addGestureRecognizer:singleTapRecognizer];
UILongPressGestureRecognizer *longPressRecognizer = [[UILongPressGestureRecognizer alloc]initWithTarget:self action:#selector(didLongPress:)];
[longPressRecognizer setDelegate:self];
longPressRecognizer.allowableMovement = 1.0f;
longPressRecognizer.minimumPressDuration = 2.0;
[self.view addGestureRecognizer:longPressRecognizer];
As i mentioned in my comment you can do so,here is some piece of code to help you out.
UITapGestureRecognizer * recognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleTap:)];
recognizer.delegate = self;
[view addGestureRecognizer:recognizer];
UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc]
initWithTarget:self
action:#selector(handleLongPress:)];
longPress.minimumPressDuration = 2.0;
[view addGestureRecognizer:longPress];
and here are are some links too for your better understanding:-
https://developer.apple.com/library/ios/documentation/uikit/reference/UILongPressGestureRecognizer_Class/Reference/Reference.html
https://developer.apple.com/library/ios/documentation/uikit/reference/UITapGestureRecognizer_Class/Reference/Reference.html
Hope this will help you out.
Related
I have a UILabel and when i double tap on it ,it should assign value of Label to the other view's UITextView otherwise next view's textview should be empty.
UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapped:)];
[tapRecognizer setNumberOfTapsRequired:1];
[tapRecognizer setDelegate:self];
[holderView addGestureRecognizer:tapRecognizer];
tapRecognizer = nil;
UITapGestureRecognizer *doubleTapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(LaunchText)];
[doubleTapRecognizer setNumberOfTapsRequired:2];
[doubleTapRecognizer setDelegate:self];
[holderView addGestureRecognizer:doubleTapRecognizer];
holderView.userInteractionEnabled=YES;
[tapRecognizer requireGestureRecognizerToFail:doubleTapRecognizer];
/*n=[SingleTon getInstance];
n.Name=textLabel.text;*/
if (doubleTapRecognizer.numberOfTapsRequired==2) {
n.Name=#"hi";
}
/* if (doubleTapRecognizer.numberOfTapsRequired==2) {
n.Name=textLabel.text;
}*/
else{
//n.Name=textLabel.text;
n.Name=#"hellow";
}
-(void) LaunchText
{
[self performSegueWithIdentifier:#"textAdd" sender:self];
}
I am always getting if condition, else part never runs, What is the issue with my code?
Please try below code.
//first add single tap
UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(singleT:)];
[tapRecognizer setNumberOfTapsRequired:1];
[holderView addGestureRecognizer:tapRecognizer];
//now add double tap
UITapGestureRecognizer *doubleTapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(doubleT:)];
[doubleTapRecognizer setNumberOfTapsRequired:2];
[holderView addGestureRecognizer:doubleTapRecognizer];
holderView.userInteractionEnabled=YES;
[tapRecognizer requireGestureRecognizerToFail:doubleTapRecognizer];
Now Implement Single Tap and Double Tap Method
-(void)singleT:(UITapGestureRecognizer *)gest
{
NSLog(#"Single");
}
-(void)doubleT:(UITapGestureRecognizer *)gest
{
NSLog(#"double");
}
Maybe this will help you.
doubleTapRecognizer.numberOfTapsRequired==2 is the value you set to how many times the user has to tap to set off the gesture recognizer. it you want to allow for single and double taps you can keep a count on the gesture recognizer target and see how many times they've tapped over a giving time, like 0.2 secs or whatever time you want. I'm not 100% sure but you could also try to add two gestures to the label one for numberOfTapsRequired = 1 and numberOfTapsRequired = 2 and have them both perform different functions. Again i'm not sure on the two recognizers but you could give it a try and try the other method otherwise.
Today I tried to add an additional UILongPressGestureRecognizer to an UISwitch, which did not really work. My code is the following:
UILongPressGestureRecognizer *lpgr = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(doSomething:)];
[lpgr setDelaysTouchesBegan:YES];
[lpgr setDelaysTouchesEnded:YES];
[lpgr setCancelsTouchesInView:YES];
[self.switcher addGestureRecognizer:lpgr];
in the viewDidLoad method of the viewController that is the parent viewController of that switch. (the switcher is an instance variable, set through a storyboard. The IBOutlet is set properly from the UISwitch to the switcherProperty of its viewController).
On a couple of other controls (like a UIButton, UISlider, UIStepper and so on) this works, even without the touches cancelled or delayed, and perfectly triggers the target method. However, with my switch, it refuses that behavior.
I have tried removing any other gestureRecognizer on the UISwitch by iterating through all gestureRecognizers on that switch and calling [switcher removeGestureRecognizer: ... ], I´ve also set all of them to require my longPressGestureRecognizer to fail. Other types of gestureRecognizers don´t fire as well.
As far as I understand, GestureRecognizers will receive touches, before the view or control, which they belong to, receives them. Thus, setCancelsTouchesInView:YES and setDelaysTouchesInView:YES should enable the gestureRecognizer to handle every single gesture until it fails or succeeds, without the view knowing, right?
--------------EDIT------------------
The whole content of my method:
- (void)viewDidLoad
{
[super viewDidLoad];
UIGestureRecognizer *lpgr = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(edit:)];
[self.view addGestureRecognizer:lpgr];
lpgr = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(edit:)];
[self.button addGestureRecognizer:lpgr];
lpgr = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(edit:)];
[self.slider addGestureRecognizer:lpgr];
lpgr = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(edit:)];
[self.segmentedControl addGestureRecognizer:lpgr];
lpgr = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(edit:)];
[self.switcher addGestureRecognizer:lpgr];
lpgr = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(edit:)];
[self.stepper addGestureRecognizer:lpgr];
}
As I said, for the other controls this is working, only the switch does not want to work
try with it
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
// Disallow recognition of tap gestures in the segmented control.
if ((touch.view == yourSwitch)) {//change it to your condition
return NO;
}
return YES;
}
make sure you confirm UIGestureRecognizerDelegate for it to work.
What are the different ways to recognize a UIButton being touched?
IBAction doesn't seem to be working with what I want, to my knowledge, I could probably use a gesture recognizer and check if the button's location was tapped, but is there any other way?
Try UITapGestureRecognizer.
//-- For identifing touch recognize
UITapGestureRecognizer *singleTapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(touchIdentifier:)];
singleTapGestureRecognizer.numberOfTapsRequired = 1;
singleTapGestureRecognizer.enabled = YES;
singleTapGestureRecognizer.cancelsTouchesInView = NO;
[your_button addGestureRecognizer:singleTapGestureRecognizer];
Method for operation
-(void)touchIdentifier:(UITapGestureRecognizer*)gesture
{
NSLog(#" Current button ID %d \n",gesture.view.tag);
}
hello U can go with the UISwipe Recognier
UISwipeGestureRecognizer *swipeRight = [[UISwipeGestureRecognizer alloc]
initWithTarget:self action:#selector(handleSwipe:)];
swipeRight.direction = UISwipeGestureRecognizerDirectionRight;
[imgView_ addGestureRecognizer:swipeRight];
[swipeRight release];
UISwipeGestureRecognizer *swipeLeft = [[UISwipeGestureRecognizer alloc]
initWithTarget:self action:#selector(handleSwipe:)];
swipeLeft.direction = UISwipeGestureRecognizerDirectionLeft;
[imgView_ addGestureRecognizer:swipeLeft];
[swipeLeft release];
But DO NOT forget to set UserInteractionEnabled for the View
I have this code in viewDidLoad:
UILongPressGestureRecognizer *change = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(dragGestureChange:)];
[imageView addGestureRecognizer:change];
for (UILongPressGestureRecognizer *gestureRecognizer in imageView.gestureRecognizers)
{
[gestureRecognizer requireGestureRecognizerToFail:change];
}
when I call the class where is this code, the first time it's all ok , but the second time it crash because EXC_BAD_ACCESS; it don't happens if instead of an imageView I use a scrollView, why???
With this code, you are requiring all recognizers (including change) to fail for change to succeed, which cannot be good
UILongPressGestureRecognizer *change = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(dragGestureChange:)];
[imageView addGestureRecognizer:change];
for (UILongPressGestureRecognizer *gestureRecognizer in imageView.gestureRecognizers)
{
[gestureRecognizer requireGestureRecognizerToFail:change];
}
you should change it to this
UILongPressGestureRecognizer *change = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(dragGestureChange:)];
for (UILongPressGestureRecognizer *gestureRecognizer in imageView.gestureRecognizers)
{
[gestureRecognizer requireGestureRecognizerToFail:change];
}
[imageView addGestureRecognizer:change];
And you should release change here. Don't know if that will actually solve your problem, can't see anything else wrong in what you posted.
Maybe try this: UIButtonLongTab. Use the Background-Image for your Images. I use this in an App within a ScrollView and it works without problem.
I've two UITapGestureRecognizer: singleTap and doubleTap initialized with two different actions.
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleSingleTap:)];
UITapGestureRecognizer *doubleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleDoubleTap:)];
[singleTap requireGestureRecognizerToFail:doubleTap];
[doubleTap setNumberOfTapsRequired:2];
[imageView addGestureRecognizer:doubleTap];
[imageView addGestureRecognizer:singleTap];
When I run my app in simulator the single tap responds correctly but not the double tap ! When I double clicks nothings happens, I suppose iOS dose recognize the double tap because the action of single tap doesn't being called (due to [singleTap requireGestureRecognizerToFail:doubleTap];), but I can't understand why doesn't it do the action handleDoubleTap.
I think the problem is that UIImageView and UILabel both override the default value of YES for the userInteractionEnabled property, and sets it to NO.
Add imageView.userInteractionEnabled = YES; and try again.
The following code works for me:
- (void)handleTap:(UIGestureRecognizer*)gr {
NSLog(#"----------------- tap ----------------");
}
- (void)handleDoubleTap:(UIGestureRecognizer*)gr {
NSLog(#"================= double tap ============");
}
- (XXXView*)createXXXView {
XXXView *view = [[[XXXView alloc] init] autorelease];
view.xxx=...;//irrelevant
UITapGestureRecognizer *dtr = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleDoubleTap:)];
dtr.numberOfTapsRequired = 2;
UIGestureRecognizer *tr = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleTap:)];
[tr requireGestureRecognizerToFail:dtr];
[view addGestureRecognizer:tr];
[view addGestureRecognizer:dtr];
return view;
}