UITapGesture recognise tap only border wise of UIImageView - ios

Here is the code:
This section is written on **-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath**
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(imageDispalyFullScreenTapped:)];
singleTap.numberOfTapsRequired = 1;
singleTap.delegate=self;
cell.imgDisplay.userInteractionEnabled = YES;
[cell.imgDisplay addGestureRecognizer:singleTap];
Next I have implemented the delegate, i.e. **UIGestureRecognizerDelegate**
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
return YES;
}
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
return YES;
}
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{
return YES;
}
Now implemented the selector when UIImageView getting tapped
-(void)imageDispalyFullScreenTapped:(UITapGestureRecognizer*)gesture
{
UIView *tappedView = gesture.view;
UITableViewCell *cell=[self getSuperViewOfType:[UITableViewCell class] FromView:tappedView];
NSIndexPath *indexPath=[tblChat indexPathForCell:cell];
Sock_ModelChat *objChat=[arrDisplay objectAtIndex:indexPath.row];
if ([objChat.strUrlLocal stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]].length>0) {
imgSelectedDisplay=[[Sock_DB sharedInstance] getImageForName:objChat.strUrlLocal];
ImageDisplayerViewController *imageDisplayer=[ImageDisplayerViewController sharedInstance];
imageDisplayer.delegate=self;
[self addChildViewController:imageDisplayer];
imageDisplayer.view.frame=CGRectMake(0, 0, CGRectGetWidth([UIScreen mainScreen].bounds), CGRectGetHeight([UIScreen mainScreen].bounds));
[self.view addSubview:imageDisplayer.view];
[imageDisplayer didMoveToParentViewController:self];
}
}
But the problem is whenever tapping on the border side or edge side of the image view, the tap on image view getting detected and the selector imageDispalyFullScreenTapped fired.But when tapping on the center or near the center, tap is not getting detected and so the related selctor also not firing.
I am working on XCode Version 8.0 (8A218a) and iOS 10.0.

May be UserInteraction is disabled in your case
then you can add gesture like :
let gesture:UITapGestureRecognizer = UITapGestureRecognizer.init(target:self, action:#selector(handleTap))
gesture.numberOfTapsRequired = 1
gesture.delegate = self
cell.imageView?.addGestureRecognizer(gesture)
then add below function in your viewcontroller
func handleTap(sender: UITapGestureRecognizer? = nil) {}

Related

UITableView swipe gesture conflicts with UITableViewCell swipe

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

UITapGestureRecognizer blocks touch event for UIButton in subview

I believe I have an issue with UITapGestureRecognizer for dismissing keyboard when tapping in chatroom area preventing or blocking touch to the previewCancelButton. Here below are my relevant codes:
BaseTemplateVC.m
- (void)addDismissKeyboardGesture {
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(dismissKeyboard:)];
tapGesture.cancelsTouchesInView = NO;
tapGesture.delegate = self;
self.view.tag = 111;
[self.view addGestureRecognizer:tapGesture];
}
- (void) dismissKeyboard:(id)sender {
UITapGestureRecognizer *gesture = sender;
UIView *view = gesture.view;
NSLog(#"%ld", (long)view.tag);
[self.view endEditing:YES];
}
ChatroomVC.m
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
//Disallow recognition of tap gestures in the segmented control.
if (([touch.view isKindOfClass:[UIButton class]])) {
NSLog(#"noooooooo");
return NO;
}
return YES;
NSLog(#"yesssssss");
}
InputFunctionView.m
- (void)selectedSticker:(NSString *)stickerURLString {
/* Sticker preview subview */
stickerPreviewView = [[UIImageView alloc] initWithFrame:CGRectMake(0, -120, FrameWidth, 120)];
stickerPreviewView.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.5f];
stickerPreviewView.userInteractionEnabled = YES;
[self addSubview:stickerPreviewView];
[self bringSubviewToFront:stickerPreviewView];
/* Initialise previewCancelButton */
self.previewCancelButton = [UIButton buttonWithType:UIButtonTypeCustom];
self.previewCancelButton.frame = CGRectMake(Main_Screen_Width-30, SpaceForItems-120, 20, 20);
[self.previewCancelButton setBackgroundImage:[UIImage imageNamed:#"btn_previewcancel.png"] forState:UIControlStateNormal];
[self.previewCancelButton setBackgroundImage:[UIImage imageNamed:#"btn_previewcancel.png"] forState:UIControlStateHighlighted];
[self.previewCancelButton addTarget:self action:#selector(cancelStickerPreviewButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
[self addSubview: self.previewCancelButton];
}
/* Cancel sticker preview subview */
- (void)cancelStickerPreviewButtonPressed:(id)sender {
NSLog(#"cancel sticker preview");
[self.previewCancelButton removeFromSuperview];
[stickerPreviewView removeFromSuperview];
}
Now the previewCancelButton is correctly on right top corner of stickerPreviewView but unable to receive touch event to it. When I touch the button it shows "111" in the console and when I traced back I found BaseTemplateVC.m that contains addDismissKeyboardGesture method, so I believe this may cause the issue.
Anyone can guide me to some solutions. That'd be really appreciated. Thanks in advance.
Progress: I have modified gestureRecognizer method in ChatroomVC.m so now it can ignore tap gesture on the button but the problem remains action for the button doesn't get fired.
Just take a try with this, i guess it will work.
Use the shouldReceiveTouch delegate method of gesture, and return NO when the touch.view is button class.
So when it finds button It will discard the gesture and take button action.
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
// Block the recognition of tap gestures in the button.
if (([touch.view isKindOfClass:[UIButton class]])) {
return NO;
}
return YES;
}
Here is the demo implementation :
I have taken the button on main view of view controller in the story board.
- (void)viewDidLoad {
[super viewDidLoad];
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapGestureClicked:)];
tapGesture.delegate = self;
[self.view addGestureRecognizer:tapGesture];
}
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
// Disallow recognition of tap gestures in the segmented control.
if (([touch.view isKindOfClass:[UIButton class]])) {
return NO;
}
return YES;
}
- (IBAction)btnTestClicked:(UIButton *)sender {
NSLog(#"test button click");
}
- (void)tapGestureClicked:(UIGestureRecognizer *)recog
{
NSLog(#"tap gesture clicked");
}
Hope it helps.
Happy coding ...
I found a solution to this by using below code in GestureRecogniser delegate method:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
if ([touch.view isDescendantOfView:IFView.stickerPreviewView]) {
return NO;
}
return YES;
}
It specifies exactly what subview in this case IFView.stickerPreviewView is to return NO. Also in InputFunctionView, use this instead to add the subview:
[self.superview addSubview:_stickerPreviewView];

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 works on simulator but never on the device

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!

how to know if UITapGestureRecognizer has been add to subview

I adding subviews programmatic. for each subview I'm adding a gesture reconognizer:
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
imageView.frame = CGRectMake((position*1024)+200,0,image.size.width,image.size.height);
UITapGestureRecognizer *singleFingerTap = [[UITapGestureRecognizer alloc]
initWithTarget:self action:#selector(singleFingerTap:)];
singleFingerTap.numberOfTapsRequired = 1;
[imageView addGestureRecognizer:singleFingerTap];
[singleFingerTap release];
but the tap is not responding how can I verify the gesture has been add it to the subview ?
Add this after your code:
NSLog(#"imageView.gestureRecognizers: %#", [imageView.gestureRecognizers description]);
If you have properly added gestureRecognizers it will print the description of each to the console. If not, it will show (NULL) or an empty array in the console.
You can also set the gesture recognizer delegate:
[singleFingerTap setDelegate:self];
Then add the delegate method and set a break point to make sure it is getting called:
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
NSLog(#"gestureRecognizerShouldBegin: called");
return YES;
}
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
NSLog(#"shouldReceiveTouch: called");
return YES;
}

Resources