I am working on app in which I want both short long gesture in same view, I added but issue is I'm facing is that short gesture end always call, Need your help how to do that in right way. Below is my code.
UILongPressGestureRecognizer *longGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(longGestureOnFormFields:)];
longGesture.minimumPressDuration = 1.0f;
[longGesture setDelegate:self];
[self addGestureRecognizer:longGesture];
UILongPressGestureRecognizer *shortGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(shortGesture:)];
shortGesture.minimumPressDuration = 0.1f;
[shortGesture setDelegate:self];
[self addGestureRecognizer:shortGesture];
- (void)longGestureOnFormFields:(UIGestureRecognizer*) recogniser
{
if (recogniser.state == UIGestureRecognizerStateEnded ) {
}
- (void)shortGesture:(UIGestureRecognizer*) recogniser
{
if (recogniser.state == UIGestureRecognizerStateEnded ) {
}
You can manage that by using one UITapGestureRecognizer like,
self.view.userInteractionEnabled = YES;
UILongPressGestureRecognizer *longGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(longGestureOnFormFields:)];
longGesture.minimumPressDuration = 1.0f;
[longGesture setDelegate:self];
[self.view addGestureRecognizer:longGesture];
UITapGestureRecognizer *recog = [[UITapGestureRecognizer alloc]initWithTarget:self action:#selector(testm)];
[self.view addGestureRecognizer:recog];
and your methods smething like,
-(void)testm{
NSLog(#"tap");
}
-(void)longGestureOnFormFields : (UILongPressGestureRecognizer*)sender{
if (sender.state == UIGestureRecognizerStateEnded ) {
NSLog(#"long press gesture");
}
}
I have added gesture recognizer in viewDidload i.e in viewcontroller so i have add it to self.view if you have subclass UIVIew and adding this to that view then add it on self like [self addgesture...] as shown in question!
Related
I am working on an application which works like a remote control of different devices like Game Console, Set-top Box, etc.
Application contains different type of controls like gesture and buttons to perform events as remote.
Single gesture view contains multiple gesture recognizer as follow:
1 finger Tap using UITapGestureRecognizer
2 finger Tap using UITapGestureRecognizer
1 finger swipe using UISwipeGestureRecognizer
2 finger swipe using UISwipeGestureRecognizer
My requirement is to implement 1 finger Swipe gesture recognizer along with hold event. So, that will continue my swipe action until user will not remove its finger from the view.
I have tried UILongPressGestureRecognizer after UISwipeGestureRecognizer but this didn’t work for me because it is executing along with Swipe movement. And I want this after Swipe end, but finger will not remove.
My code snippet :
-(void) gestureView:(UIView*)viewGesture {
UISwipeGestureRecognizer *swipeGestureSingleRight;
UISwipeGestureRecognizer *swipeGestureSingleLeft;
UISwipeGestureRecognizer *swipeGestureSingleUp;
UISwipeGestureRecognizer *swipeGestureSingleDown;
swipeGestureSingleUp = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(swipeGestureSingle_Handle:)];
[swipeGestureSingleUp setDelegate:self];
[swipeGestureSingleUp setDirection:(UISwipeGestureRecognizerDirectionUp)];
[swipeGestureSingleUp setNumberOfTouchesRequired:1];
[viewGesture addGestureRecognizer:swipeGestureSingleUp];
swipeGestureSingleDown = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(swipeGestureSingle_Handle:)];
[swipeGestureSingleDown setDelegate:self];
[swipeGestureSingleDown setDirection:(UISwipeGestureRecognizerDirectionDown)];
[swipeGestureSingleDown setNumberOfTouchesRequired:1];
[viewGesture addGestureRecognizer:swipeGestureSingleDown];
swipeGestureSingleRight = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(swipeGestureSingle_Handle:)];
[swipeGestureSingleRight setDelegate:self];
[swipeGestureSingleRight setDirection:(UISwipeGestureRecognizerDirectionRight)];
[swipeGestureSingleRight setNumberOfTouchesRequired:1];
[viewGesture addGestureRecognizer:swipeGestureSingleRight];
swipeGestureSingleLeft = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(swipeGestureSingle_Handle:)];
[swipeGestureSingleLeft setDelegate:self];
[swipeGestureSingleLeft setDirection:(UISwipeGestureRecognizerDirectionLeft)];
[swipeGestureSingleLeft setNumberOfTouchesRequired:1];
[viewGesture addGestureRecognizer:swipeGestureSingleLeft];
longPressGestureOnSwipe = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(longPressGesture_Handle:)];
longPressGestureOnSwipe.minimumPressDuration = 0.03;
longPressGestureOnSwipe.delegate = self;
[viewGesture addGestureRecognizer:longPressGestureOnSwipe];
isSwipeEnd = false;
[longPressGestureOnSwipe setEnabled:isSwipeEnd];
}
- (void)swipeGestureSingle_Handle:(UISwipeGestureRecognizer*)sender {
if (sender.state == UIGestureRecognizerStateEnded) {
singleTouchSwipeSenderDirection = sender.direction;
isSwipeEnd = true;
[longPressGestureOnSwipe setEnabled:isSwipeEnd];
}
}
-(void)longPressGesture_Handle:(UILongPressGestureRecognizer*)sender {
if (sender.state == UIGestureRecognizerStateEnded) {
isSwipeEnd = false;
[longPressGestureOnSwipe setEnabled:isSwipeEnd];
}
}
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
return YES;
}
- (void)touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event {
if (isSwipeEnd) {
[super touchesBegan:touches withEvent:event];
} else {
return;
}
}
Please suggest me correction or solution for my requirement.
Thanks in advance!
I am new in IOS Dev, was searching onclick event for UIView and i found this code that worked perfectly. But it doesnt call specific UIView as i am using multiple UIViews and want to add event on all of them separately while this code calls handleSingleTap onclick of either UIView. plz help..
- (void)viewDidLoad
{
[super viewDidLoad];
UITapGestureRecognizer *singleFingerTap =
[[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleSingleTap:)];
[self.view addGestureRecognizer:singleFingerTap];
}
- (void)handleSingleTap:(UITapGestureRecognizer *)recognizer {
CGPoint location = [recognizer locationInView:[recognizer.view superview]];
NSLog(#"Clicked");
}
You can create UITapGestureRecognizer and add it to the views you want it to be clicked.
You can also set up tag property on each view to find out which view was clicked.
For example:
UITapGestureRecognizer *singleFingerTap1 =
[[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleSingleTap:)];
view1.tag = 1;
[view1 addGestureRecognizer:singleFingerTap1];
UITapGestureRecognizer *singleFingerTap2 =
[[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleSingleTap:)];
view2.tag = 2;
[view2 addGestureRecognizer:singleFingerTap2];
//..and so on
- (void)handleSingleTap:(UITapGestureRecognizer *)recognizer {
UIView *viewClicked = recognizer.view;
NSLog(#"Clicked: %d", viewClicked.tag);
}
The other solution is add one gesture recogniser to the main view (the view which hold the others view, something as you posted) and in handleSingleTap: method check if the point is inside the view:
BOOL isPointInsideView1 = [view1 pointInside:location withEvent:nil];
BOOL isPointInsideView2 = [view1 pointInside:location withEvent:nil];
But ic can failed when one view override another.
I have a view controller with 3 UIWebViews, all with the same frame overlaying each other. I use three buttons to switch between them (similar to a segment control). I want to attach a tap gesture recognizer to the webview so that tapping each webview leads to a new controller. However, only the UITapGestureRecognizer for the first webview fires. Can anyone tell me how to get the other two gesture recognizers to fire? This is my code:
- (IBAction)changeWebView:(id)sender
{
UIButton *button = (UIButton *)sender;
switch (button.tag) {
case 0:
{
[self.view bringSubviewToFront:WebView1];
for (UITapGestureRecognizer *recognizer in WebView2.gestureRecognizers) {
[WebView2 removeGestureRecognizer:recognizer];
}
for (UITapGestureRecognizer *recognizer in WebView3.gestureRecognizers) {
[WebView3 removeGestureRecognizer:recognizer];
}
UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(showFullScreen1)];
tapGestureRecognizer.delegate = self;
[WebView1 addGestureRecognizer:tapGestureRecognizer];
}
break;
case 1:
{
[self.view bringSubviewToFront:WebView2];
for (UITapGestureRecognizer *recognizer in WebView1.gestureRecognizers) {
[WebView1 removeGestureRecognizer:recognizer];
}
for (UITapGestureRecognizer *recognizer in WebView3.gestureRecognizers) {
[WebView3 removeGestureRecognizer:recognizer];
}
UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(showFullScreen2)];
tapGestureRecognizer.delegate = self;
[WebView2 addGestureRecognizer:tapGestureRecognizer];
}
break;
case 2:
{
[self.view bringSubviewToFront:WebView3];
for (UITapGestureRecognizer *recognizer in WebView1.gestureRecognizers) {
[WebView1 removeGestureRecognizer:recognizer];
}
for (UITapGestureRecognizer *recognizer in WebView2.gestureRecognizers) {
[WebView2 removeGestureRecognizer:recognizer];
}
UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(showFullScreen3)];
tapGestureRecognizer.delegate = self;
[WebView3 addGestureRecognizer:tapGestureRecognizer];
}
break;
default:
break;
}
}
This sounds like a design issue. Why don't you only have one one UIView and render the correct content depending on what button was pressed. You can then have only one gesture recognizer that will load the proper controller (or perform the correct segue) also depending on the button.
Add UITapGestureRecognizer to a a view and add all 3 UIWebview as a subview on them.Than whenever you detect UITapGestureRecognizer to be tapped get the tag from segmentedController or button whatever you are using and find which one was tapped.
Don't add UITapGestureRecognizer and remove it again and again.
I have 2 imageview, and I want them to rotate when they are clicked. This is my code:
UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapRecognizerMethod:)];
Then in the tapRecognizerMethod:
- (void)tapRecognizerMethod:(UITapGestureRecognizer *)tapRecognize
{
if (tapRecognize == tapRecognizer) // tapRecognizer is the first imageviews recognizer
{
if (tapRecognize.state == what should go here?
{
//do something
}
}
}
What should go after tapRecognize ==?
- (void)tapRecognizerMethod:(UITapGestureRecognizer *)tapRecognize{
if (tapRecognize == tapRecognizer){
if (tapRecognize.state == UIGestureRecognizerStateEnded){
UIImageView *imgView = (UIImageView*)[tapRecognize view];
//Now need to rotate the image
}
}
}
Have a look at the following link:
rotating Image
- (void)handleTap:(UITapGestureRecognizer *)tapRecognize
{
if (tapRecognize == tapRecognizer)
{
CGAffineTransform transform = CGAffineTransformRotate(lineImage.transform, 90);
[lineImage setTransform:transform];
}
}
and make sure you have enabled the uesr interaction of imageviews,
[imageView1 setUserInteractionEnabled:YES];
[imageView2 setUserInteractionEnabled:YES];
If you actually requires a flip rotation you better chose below swipe gestures.
UISwipeGestureRecognizer *swipeLeft = [[UISwipeGestureRecognizer alloc]
initWithTarget:self
action:#selector(handleSwipeLeft:)];
swipeLeft.direction = UISwipeGestureRecognizerDirectionLeft;
[imageView addGestureRecognizer:swipeLeft];
[swipeLeft release];
UISwipeGestureRecognizer *swipeRight = [[UISwipeGestureRecognizer alloc]
initWithTarget:self
action:#selector(handleSwipeRight:)];
swipeRight.direction = UISwipeGestureRecognizerDirectionRight;
[imageView addGestureRecognizer:swipeRight];
[swipeRight release];
On handler method you give an animation for separate flip right and left
if(isActiveFlipLeft)
{
[UIView transitionWithView:imageSnap
duration:1.0f
options:UIViewAnimationOptionTransitionFlipFromLeft
animations:^{
imageSnap.backgroundColor = [UIColor colorWithRed:187.0/225.0 green:187.0/225.0 blue:187.0/225.0 alpha:1.0];
imageSnap.image = image;
} completion:NULL];}
else if (isActiveFlipRight)
{
[UIView transitionWithView:imageSnap
duration:1.0f
options:UIViewAnimationOptionTransitionFlipFromRight
animations:^{
imageSnap.backgroundColor = [UIColor colorWithRed:187.0/225.0 green:187.0/225.0 blue:187.0/225.0 alpha:1.0];
imageSnap.image = image;
} completion:NULL];}
The below code is for just a simple tap gesture. you will get call on handleSingleTap:
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleSingleTap:)];
[singleTap setNumberOfTapsRequired:1];
[imageView addGestureRecognizer:singleTap];
[singleTap release];
Gesture handler
- (void)handleSwipeLeft:(UIGestureRecognizer *)gestureRecognizer;
- (void)handleSwipeRight:(UIGestureRecognizer *)gestureRecognizer;
- (void)handleSingleTap:(UIGestureRecognizer *)gestureRecognizer;
If you requires real rotation you can use
imageview.transform = CGAffineTransformMakeRotation( 270.0/180*M_PI );
something like in your gesture handler
I add singTap and doubleTap to a view like the code below:
-(void)awakeFromNib{
[self setUserInteractionEnabled:YES];
//
UITapGestureRecognizer *doubleTapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleDoubleTapGesture:)];
doubleTapGesture.numberOfTapsRequired = 2;
[self addGestureRecognizer:doubleTapGesture];
UITapGestureRecognizer *singleTapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleSingleTapGesture:)];
singleTapGesture.numberOfTapsRequired = 1;
[self addGestureRecognizer:singleTapGesture];
}
-(void)handleSingleTapGesture:(UITapGestureRecognizer *)singleTapGesture{
[[self delegate] singleTapOnView];
}
-(void)handleDoubleTapGesture:(UITapGestureRecognizer *)doubleTapGesture{
[[self delegate] doubleTapOnView];
}
When doubleTap the singleTap also fire. How to disable singleTap when doubleTap? Thanks!
Tell the single-tap recognizer that it requires the double-tap recognizer to fail before it triggers:
[singleTapGesture requireGestureRecognizerToFail:doubleTapGesture];
(This is actually the canonical example in the UIGestureRecognizer docs for this method.)