iOS UITapGestureRecognizer and UIWebView - ios

I have a viewcontroller, which contains a web view.
I'd like to add two gesturerocignizers to the viewController's view:
One UITapGestureRecognizer and one UILongPressureGestureRecognizer.
Here's the code:
UILongPressGestureRecognizer *longPressGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(backToDashboards:)];
UITapGestureRecognizer *doubleTapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(backToDashboards:)];
doubleTapGesture.numberOfTapsRequired = 2;
doubleTapGesture.delegate = self;
[self.view addGestureRecognizer:longPressGesture];
[self.view addGestureRecognizer:doubleTapGesture];
My view hierarchy:
-ViewController
|
|-View (added the gesture recognizers for this view)
|-WebView
I've added the shouldRecognizeSimultaneouslyWithGestureRecognizer method with return YES
But if I long press the screen nothing happens, only if the press' location is on a place where nothing can be scrolled in the webview.
The double tap recognizer doesn't work at all.
Any idea?
Thank you in advance!

I suspect that because your webview is on top of your view, the app doesnt know if you are tapping the webview or self.view. Check out this reply How to detect of tap gesture is from uiwebview or self.view?

try with below code.Where u r adding gester in you code?
below code is working for me.
- (void)viewDidLoad
{
[super viewDidLoad];
UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc]initWithTarget:self action:#selector(handleLongPress:)];
longPress.numberOfTouchesRequired = 2;
[self.view addGestureRecognizer:longPress];
// if u want to add gesture for u webview,
//[self.webview addGestureRecognizer:longPress]
}
-(void)handleLongPress:(UILongPressGestureRecognizer *)gesture
{
}
//You should enable simultaneous gesture recognition
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
return YES;
}

Related

How to set frame for TapGesture Recognizer

I have an imageview and I want to tap on only one side of imageview. Is it possible to set frame for a gesture? Can anyone help with a solution?
Use UIGestureRecognizerDelegate, i think you can get the idea on how to compare:
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
if ([touch locationInView:yourview].x < somePoint.x) {
return false;
} else {
return true;
}
}
you could overlay a view on top of the imageview and add the tap recognizer to this new view, something like this will make the left hand side of the image tapable
UIView tapView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, imageView.frame.size.width/2, imageView.frame.size.height)];
[imageView addSubView:tapView]
UITapGestureRecognizer *singleFingerTap =
[[UITapGestureRecognizer alloc] initWithTarget:self
action:#selector(handleSingleTap:)];
[tapView addGestureRecognizer:singleFingerTap];
You can simply put UIView on top of your imageView with frame as per your requirement and put tap gesture on that UIView.
You can do this by storyboard / xib or by programmatically.
By programmatically, for example - you want to tap only within the area with width of 50 px of your imageView. For this:
UIView *vw = [[UIView alloc] initWithFrame:CGRectMake(imgView.frame.origin.x, imgView.frame.origin.y, 50, imgView.frame.size.height)];
// add gesture to view
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleTapGesture:)];
tapGesture.numberOfTapsRequired = 2;
[vw addGestureRecognizer:tapGesture];
[imgView addSubview:vw];
now to handle your double tap
-(void)handleTapGesture:(UITapGestureRecognizer *)gesture
{
// handle double tap
}

UITableView and UIView gesture conflict

I'm trying to add UITableView inside UIView but I got problem with gesture recognizer. This is my code:
_subView = [[UIView alloc] initWithFrame:CGRectMake(0, screenRect.size.height-100, screenRect.size.width, 300)];
_subView.backgroundColor = [UIColor colorWithRed:0.110f green:0.192f blue:0.298f alpha:1.00f];
[self.view addSubview:_subView];
UITapGestureRecognizer *singleFingerTap =
[[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(subViewToggle)];
[_subView addGestureRecognizer:singleFingerTap];
_moreTable = [[UITableView alloc] initWithFrame:CGRectMake(0,50, screenRect.size.width, 240)];
//Transforme to HOR scroll ;
CGRect frame = _moreTable.frame;
_moreTable.transform = CGAffineTransformRotate(CGAffineTransformIdentity, k90DegreesCounterClockwiseAngle);
_moreTable.frame = frame;
[_moreTable registerNib:[UINib nibWithNibName:#"MoreTableViewCell" bundle:nil] forCellReuseIdentifier:#"moreCell"];
_moreTable.backgroundColor = [UIColor groupTableViewBackgroundColor];
_moreTable.delegate = self;
_moreTable.dataSource = self;
[_subView addSubview:_moreTable];
[_subView bringSubviewToFront:_moreTable];
The problem is when I click on table cell instead of executing didSelectRowAtIndexPath method he execute the subViewToggle Method. I tried to bring my tableView to front but didn't help
your tap gesture eat the touch. there are two way you can deal:
first, you can implement - gestureRecognizer:shouldReceiveTouch: delegate method, and decide if tap gesture should occur.
second, you also can set cancelsTouchesInView property of tap to NO, so tableView will receive touch. but tap will receive touch at the some time too.
Try implementing the UIGestureRecognizerDelegate protocol's gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer:
This should call both your didSelectRow and GestureRecognizer
https://developer.apple.com/library/prerelease/ios/documentation/UIKit/Reference/UIGestureRecognizerDelegate_Protocol/index.html#//apple_ref/occ/intfm/UIGestureRecognizerDelegate/gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer:
Please try to use like this
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
if ([touch.view == _moreTable]) {
return NO;
}
return YES;
}
To solve this Problem I've changed the UIView Gesture from single finger tap to moveUP and moveDown gesture.
Note that I've tried only #dharmbir Solution and It haven't worked for me.
Update Also this solution, implementing the shouldReciveTouches, worked for the tapGesture and her's the code snippet :
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
// UITableViewCellContentView => UITableViewCell
if([touch.view.superview isKindOfClass:[UITableViewCell class]]) {
return NO;
}
// UITableViewCellContentView => UITableViewCellScrollView => UITableViewCell
if([touch.view.superview.superview isKindOfClass:[UITableViewCell class]]) {
return NO;
}
return YES;
}
//Create tap gesture for menu transparent view
UITapGestureRecognizer *rightTableTransparentViewTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(rightTableTransparentViewTapMethod:)];
[rightTableTransparentViewTap setCancelsTouchesInView:NO];
[_rightTableTransparentView addGestureRecognizer:rightTableTransparentViewTap];
- (void)rightTableTransparentViewTapMethod:(UITapGestureRecognizer *)recognizer {
//Write your code here
}

UILongPressGestureRecognizer on UISwitch does not fire

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.

How to detect of tap gesture is from uiwebview or self.view?

Hello everyone I have a uitapgesture on my view using the following code :
UITapGestureRecognizer *tap= [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(TAPGestureRecognizer)];
tap.numberOfTapsRequired=1;
tap.delegate = self;
[self.view addGestureRecognizer:tap];
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
return YES;
}
And I have a uiwebview as a subview in my UIview. The problem is that on the uivewview HTML it had a onclick(); which in turn is calling the tapgesture. Any help?
FirstView.image=[UIImage imageNamed:#"shape1.jpg"];
FirstView.tag=1;
FirstView.userInteractionEnabled=YES;
[FirstView addGestureRecognizer:[[UITapGestureRecognizer alloc]initWithTarget:self action:#selector(firstimagetouch:)]];
SecondWebView.tag=2;
SecondWebView.userInteractionEnabled=YES;
[SecondWebView addGestureRecognizer:[[UITapGestureRecognizer alloc]initWithTarget:self action:#selector(firstimagetouch:)]];
-(void)firstimagetouch:(UIGestureRecognizer *)sender
{
UIView * view=sender.view;
NSLog(#"%ld",(long)view.tag);
}
try like this first add gesture recognizer to view and then your webview according to give him tag value and get tag value. and do what you want.

How to implement swipe gesture on half view and pan gesture on other half view?

How to add a pan gesture to first half (0,0,160,480) of a view and on same view a swipe gesture on (160,0,160,480) as well?
The view is table view and on swiping left the cell content should change and on panning in right the tableview should move like facebook ios app
Take two Different UIview as SubView of mainView with Required Frame Size then add Desired Gestures :-
UISwipeGestureRecognizer *swipeGestureRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(swipeVC:)];
swipeGestureRecognizer.delegate = self;
[self.subView.view addGestureRecognizer:swipeGestureRecognizer];
UIPanGestureRecognizer *panGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(panVC:)];
panGestureRecognizer.delegate = self;
[panGestureRecognizer requireGestureRecognizerToFail:swipeGestureRecognizer];
[self.subView2.view addGestureRecognizer:panGestureRecognizer];
The Below method is called when recognition of a gesture by either gestureRecognizer or otherGestureRecognizer
- (BOOL) gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
return YES;
}

Resources