I add the gesture to view as following steps:
#interface iCarousel () <UIGestureRecognizerDelegate>
{
UIPanGestureRecognizer * mPanGesture;
UITapGestureRecognizer * mTapGesture;
}
#end
#implementation iCarousel
- (void)setUp
{
_contentView = [[UIView alloc] initWithFrame:self.bounds];
_contentView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
/
mPanGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(iCarouselDidPan:)];
mPanGesture.delegate = self;
[_contentView addGestureRecognizer:mPanGesture];
/
mTapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(iCarouselDidTap:)];
mTapGesture.delegate = self;
[_contentView addGestureRecognizer:mTapGesture];
/
self.accessibilityTraits = UIAccessibilityTraitAllowsDirectInteraction;
self.isAccessibilityElement = YES;
[self addSubview:_contentView];
}
- (id)initWithCoder:(NSCoder *)aDecoder
{
if ((self = [super initWithCoder:aDecoder]))
{
[self setUp];
}
return self;
}
- (id)initWithFrame:(CGRect)frame
{
if ((self = [super initWithFrame:frame]))
{
[self setUp];
}
return self;
}
...
- (void)iCarouselDidTap:(UITapGestureRecognizer *)tapGesture
{
...
}
- (void)iCarouselDidPan:(UIPanGestureRecognizer *)panGesture
{
...
}
...
#end
Now, the method in this class
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gesture
return me YES
But, the actions iCarouselDidPan: and iCarouselDidTap: do not fire.
The information is printed in gestureRecognizerShouldBegin: method.
(lldb) po _contentView.gestureRecognizers
<__NSArrayI 0x1572bec0>(
<UIPanGestureRecognizer: 0x16dea750; state = Possible; view = <UIView 0x16dea640>; target= <(action=iCarouselDidPan:, target=<iCarousel 0x16dea1b0>)>>,
<UITapGestureRecognizer: 0x16e8f310; state = Possible; view = <UIView 0x16dea640>; target= <(action=iCarouselDidTap:, target=<iCarousel 0x16dea1b0>)>>
)
(lldb) po gesture
<UIPanGestureRecognizer: 0x16dea750; state = Possible; view = <UIView 0x16dea640>; target= <(action=iCarouselDidPan:, target=<iCarousel 0x16dea1b0>)>>
It's only happened on devices <4s 9.3.x , 5 10.3.1> at current moment.
Try implement the following methods of protocol UIGestureRecognizerDelegate inside your iCarousel:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer
shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
return YES;
}
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer
shouldReceiveTouch:(UITouch *)touch {
return YES;
}
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer
shouldReceivePress:(UIPress *)press {
return YES;
}
Possible cases for not working gestures .
1 - You need to enable interaction of view.
[_contentView setUserInteractionEnabled:YES];
2 - Add this delegate in your class.
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldBeRequiredToFailByGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{
return YES;
}
Declare UIGestureRecognizerDelegate in .h file
Gesture definition
-(UITapGestureRecognizer*)setTapGesture{
UITapGestureRecognizer *Tap = [[UITapGestureRecognizer alloc]
initWithTarget:self action:#selector(handleTapWithGestureRecognizer:)];
Tap.delegate = self;
return Tap;
}
-(void)handleTapWithGestureRecognizer:(UITapGestureRecognizer *)TapGestureRecognizer{
NSLog(#"tap Gesture");
}
-(UIPanGestureRecognizer*)setpanGesture{
UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(handlePan:)];
[panRecognizer setMinimumNumberOfTouches:1];
[panRecognizer setMaximumNumberOfTouches:1];
return panRecognizer;
}
- (void)handlePan:(UIPanGestureRecognizer *)recognizer {
[self.view bringSubviewToFront:recognizer.view];
CGPoint touchLocation = [recognizer locationInView:self.view];
self.YOURVIEW.center = touchLocation;
}
Call Gesture or add gesture to your view
[self.YOURVIEW addGestureRecognizer:[self setTapGesture]];
[self.YOURVIEW addGestureRecognizer:[self setpanGesture]];
self.YOURVIEW.userInteractionEnabled = YES;
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{
return YES;
}
Good Luck
Happy Coding.
Related
Following is the code I have written to put 2 finger swipe on UITableView :
UISwipeGestureRecognizer *leftSwipe = [UISwipeGestureRecognizer new];
[leftSwipe addTarget:self action:#selector(nextDay)];
leftSwipe.numberOfTouchesRequired = 2;
leftSwipe.direction = UISwipeGestureRecognizerDirectionLeft;
leftSwipe.delegate = self;
[leftSwipe setCancelsTouchesInView:YES];
[tableViewTasks addGestureRecognizer:leftSwipe];
UISwipeGestureRecognizer *rightSwipe = [UISwipeGestureRecognizer new];
[rightSwipe addTarget:self action:#selector(previousDay)];
rightSwipe.numberOfTouchesRequired = 2;
rightSwipe.direction = UISwipeGestureRecognizerDirectionRight;
rightSwipe.delegate = self;
[rightSwipe setCancelsTouchesInView:YES];
[tableViewTasks addGestureRecognizer:rightSwipe];
I am using SWTableViewCell which has left and right (single tap) gestureRecognisers.
When UITableView is swiped left/right using 2 fingers, SWTableViewCell left and right gestures are also fired after that.
How to stop the conflict ?
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{
if (SWTableViewCellTouch) {
SWTableViewCellTouch = NO
return NO;
}
return YES;
}
when you touch the SWTableViewCell set a BOOL SWTableViewCellTouch to YES.
The possible solution is enable/disable the BOOl (SWTableViewCellTouch) in the touchesBegan: method as below.
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
if ([[event touchesForView:self] count] > 1) {
// Its two finger touch so set the BOOL false like
SWTableViewCellTouch = NO;
}
else if ([[event touchesForView:self] count] == 1){
// Its sigle finger touch so set the BOOL true like
SWTableViewCellTouch = YES;
}
[super touchesBegan:touches withEvent:event] ;}
Hope this will help you.
1. Implement UIGestureRecognizerDelegate in your UIViewController
2. Set leftSwipe.delegate = self; and leftSwipe.delegate = self;
3. Now check if the in its Delegate Method if UISwipeGesture have how many numberOfTouchesRequired
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
if ( [gestureRecognizer isMemberOfClass:[UISwipeGestureRecognizer class]] ) {
UISwipeGestureRecognizer *swipeGesture=(UISwipeGestureRecognizer *)gestureRecognizer ;
if(swipeGesture.numberOfTouchesRequired!=2)
{
//if Double not Double Swipe Touch Don't Linsten Gesture in your Viewcontroller
return NO;
}
}
return YES;
}
i hope this will solve your problem
I have this snippet of code in the viewDidLoad of my ViewController
UILongPressGestureRecognizer* gestureRecognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(_handleLongPress:)];
gestureRecognizer.numberOfTouchesRequired = 1;
gestureRecognizer.minimumPressDuration = 5.0;
gestureRecognizer.delegate = self;
[self.view addGestureRecognizer:gestureRecognizer];
NSLog(#"Gesture recognizers = %#",self.view.gestureRecognizers);
and the methods
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
return YES;
}
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
return YES;
}
- (void) _handleLongPress:(UIGestureRecognizer *)sender
{
if (sender.state == UIGestureRecognizerStateBegan)
NSLog(#"Started");
}
When I run this app and click on the view for 5 seconds the _handleLongPress gets trigger, however when I run the same app on the device it never hits the _handleLongPress method.. what am I missing? I do see the output that there is the long press :
2014-08-01 10:00:48.505 TestConsole[1343:60b] Gesture recognizers = (
"UILongPressGestureRecognizer: 0x14644d30; state = Possible; view = UIView 0x1453f950>; target= <(action= _handleLongPress:, target=MyViewController 0x1463a730>)>"
I put breakpoints at gestureRecognizer:shouldReceiveTouch: and it does hit that the UILongPressGestureRecognizer.. I am dumbfounded!
I have a UIScrollView as a subview in another UIScrollView I am trying to prevent scrolling from occurring in the subview and pass the touch to the superview.
- (void)viewDidLoad
{
self.outerScrollView = [[UIScrollView alloc] initWithFrame:self.view.bounds];
self.outerScrollView.showsVerticalScrollIndicator = NO;
self.gestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(handlePanGesture:)];
self.gestureRecognizer.delegate = self;
[self.tableViewController.tableView addGestureRecognizer:self.gestureRecognizer];
[self.outerScrollView addSubview:self.tableViewController.tableView];
[self.view addSubview:self.outerScrollView];
}
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
return YES;
}
- (void)handlePanGesture:(UIPanGestureRecognizer *)gesture
{
if (gesture.state == UIGestureRecognizerStateBegan) {
if (gesture.view == self.tableViewController.tableView) {
self.tableViewController.tableView.contentOffset = CGPointMake(0, 0);
// Pass to self.outerScrollView
// Trying to make self.outerScrollView take over the touch
}
}
}
I have a gesture recognizer on my view controller which I use to slide in/out the navigation bar. Unfortunately there is a bad NSZombie that makes the whole app crash when I go swipe to go to the previous controller. It's very difficult to track because it only happens in a specific view controller.
Here is the error:
[MyViewController gestureRecognizer:shouldBeRequiredToFailByGestureRecognizer:]: message sent to deallocated instance
And here is my code:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
UIPanGestureRecognizer *pgr = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(pgr:)];
pgr.delegate = self;
[self.view addGestureRecognizer:pgr];
}
- (void)pgr:(UIPanGestureRecognizer *)gesture {
// Check if this is the first touch
if (gesture.state == UIGestureRecognizerStateBegan) {
CGPoint point = [gesture locationInView:gesture.view];
self.start = point.y;
}
CGPoint point = [gesture locationInView:gesture.view];
self.currentX = point.x;
self.offsetY = point.y - self.start;
}
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
return YES;
}
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldBeRequiredToFailByGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
if ([gestureRecognizer isKindOfClass:[UIScreenEdgePanGestureRecognizer class]]) {
return YES;
}
return NO;
}
The delegate method is
- (BOOL)shouldBeRequiredToFailByGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
Try to use
- (BOOL)shouldBeRequiredToFailByGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
if ([otherGestureRecognizer isKindOfClass:[UIScreenEdgePanGestureRecognizer class]]) {
return YES;
}
return NO;
}
I have an UIView which has an UITapGestureRecognizer attached to it that I use to hide the keyboard when the user taps outside the UITextFields. Now, I also have some labels that when tapped show an UIPickerView. The labels use an UITapGestureRecognizer as well. The problem is that the events seem to canibalise themselves.
Is it possible to execute both event handlers when tapping on my labels?
Thank you.
UITapGestureRecognizer* tapForUnit = [[UITapGestureRecognizer alloc] initWithTarget:self.fridgeItemUnit action:#selector(onTap)];
[self.fridgeItemUnit addGestureRecognizer:tapForUnit];
The above code is for one of the labels. I have removed the code for the view because my labels would stop working, but it's exactly the same, only thing different is that it is attached to self.view and the function that is executed is this one:
-(void)dismissKeyboard:(UIGestureRecognizer*)gesture {
[self.fridgeItemName resignFirstResponder];
[self.fridgeItemQuantity resignFirstResponder];
}
I would implement the following method from UIGestureRecognizerDelegate:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
I attach an example:
The only thing I did on the XIB was to enabled the user interaction. An here is the .m of the UIViewController:
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
_viewRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(viewTap:)];
[_viewRecognizer setDelegate:self];
_labelRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(labelTap:)];
[_labelRecognizer setDelegate:self];
[self.view addGestureRecognizer:_viewRecognizer];
[self.label addGestureRecognizer:_labelRecognizer];
}
- (void)viewDidUnload {
[super viewDidUnload];
[_viewRecognizer release]; _viewRecognizer = nil;
[_labelRecognizer release]; _labelRecognizer = nil;
self.label = nil;
}
- (void)dealloc {
[_viewRecognizer release];
[_labelRecognizer release];
self.label = nil;
[super dealloc];
}
- (void)labelTap:(UIGestureRecognizer *)recognizer {
NSLog(#"labelTap");
}
- (void)viewTap:(UIGestureRecognizer *)recognizer {
NSLog(#"viewTap");
}
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
NSLog(#"shouldRecognizeSimultaneouslyWithGestureRecognizer");
return YES;
}
Then when tapping on the label I get the following log:
shouldRecognizeSimultaneouslyWithGestureRecognizer
shouldRecognizeSimultaneouslyWithGestureRecognizer
labelTap
viewTap
And when tapping on the view:
viewTap