I have a UIButton in my Custom UITableViewCell. I am working on some control events on that button in the UITableViewCell by the following code. This is taken from CellForRowAtIndexPath method.
cell.gestureButton.tag = indexPath.row ;
[cell.gestureButton addTarget:self action:#selector(cellTapped:) forControlEvents:UIControlEventTouchUpInside];
UILongPressGestureRecognizer *lpgr = [[UILongPressGestureRecognizer alloc]
initWithTarget:self action:#selector(cellLongPressed:)];
lpgr.minimumPressDuration = 2.0; //seconds
lpgr.delegate = self ;
[cell.gestureButton addGestureRecognizer:lpgr];
I am testing this on iOS 7 Simulator. My problem is , for the first event when UIControlEventTouchUpInside is executed , I can see the result and my cellTapped method is called properly.
But in the second case where I have assigned a UILongPressGestureRecognizer on my button , I can't see the result in simulator and cellLongPressed: method is never called. As far I understand, my code is ok. So, I would like to know , where's the problem ? Is there any problem with my code or Simulator doesn't support this feature ? Thanks in advance for your help.
I'm betting lpgr is conflicting with another gesture recognizer. Have you tried implementing UILongPressGestureRecognizer's delegate methods? You may need to set up a failure dependency. Specifically, you'll probably need to return YES in gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer:.
Make sure your cellLongPressed is declared as following.
- (void)cellLongPressed:(UIGestureRecognizer *)gestureRecognizer {
NSLog(#"cellLongPressed in action");
}
Or if its declared as following:
- (void)cellLongPressed {
NSLog(#"cellLongPressed in action");
}
Please change your gesture initializer to following:
UILongPressGestureRecognizer *lpgr = [[UILongPressGestureRecognizer alloc]
initWithTarget:self action:#selector(cellLongPressed)];
Note there is no ":" at the end of cellLongPressed selector name.
Related
I'm quite new to iOS and objective c in particular and I'm facing an issue were I'm unable to properly register a long press gesture recognizer to my view. I'm a little bit confused because I already added a tap gesture recognizer in a similar way and it worked fine.
This is how I add my long press gesture recognizer :
UITapGestureRecognizer * tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action: #selector(onTap:)];
UILongPressGestureRecognizer * longPressGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action: #selector(longPress:)];
[_pdfView addGestureRecognizer:longPressGesture];
[_pdfView addGestureRecognizer:tapGesture];
This is my longPress function:
-(void) longPress:(UILongPressGestureRecognizer *)sender {
NSLog(#"longPress");
}
This is my header file :
#interface FLTPDFSandboxController : NSObject <FlutterPlatformView, CustomPdfViewDelegate>
- (instancetype)initWithFrame:(CGRect)frame;
-(void) onTap:(UITapGestureRecognizer *)sender;
-(void) longPress:(UILongPressGestureRecognizer *)sender;
- (UIView*)view;
#end
The tap gesture is working fine for me. It is just de long press one that is not triggered consistently. In fact in some very rare times it is triggered in a somewhat random manner.
Thank you.
Hi I am developing small IOS application in which I want to display search bar and below it table view. In which I want to hide keyboard when user click outside. For that reason I am using tap recogniser but becoz of that my table view stops listening for row selection.
Here Is my code
//inside view did load
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]
initWithTarget:self
action:#selector(dismissKeyboard)];
[self.view addGestureRecognizer:tap];
-(void)dismissKeyboard {
[_searchBar resignFirstResponder];
}
but because of this my row selection of table view get disable. that mean didSelectRowAtIndexPath never get called. Any one have solution for this. Need Help. Thank you .
Try adding this line of code this will solve your problem..
tap.cancelsTouchesInView = NO;
You should implement UIGestureRecognizerDelegate and add the following:
//inside view did load
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]
initWithTarget:self
action:#selector(dismissKeyboard)];
tap.delegate = self;
[self.view addGestureRecognizer:tap];
// UIGestureRecognizerDelegate methods
#pragma mark UIGestureRecognizerDelegate methods
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
if ([touch.view isDescendantOfView:yourTableView]) {
// Don't let selections of auto-complete entries fire the
// gesture recognizer
return NO;
}
return YES;
}
There is a "Search Bar and Search Display Controller" in the Utilities panel that sounds like it would be perfect for you. This is a good tutorial that explains how to implement it. This way you won't have the keyboard issue anymore.
There is no need to use TapGestureRecognizer. Use SearchBarDisplayController
hope this will work for you
download a demo project
I have a UIView that already has a UIPanGesture implemented that works when a user drags the UIView half way up causing some action. As of now, it works just fine. Now, within the same UIView I want to implement a a UISwipeGesture so when the user swipes up, some other method would be called. I've been reading about the UIGestureRecognizerDelegate methods and I'm thinking I need to use gestureRecognizer:shouldRequireFailureOfGestureRecognizer: but I'm not sure.
I implemented the following in my viewDidLoad and got an error saying "invalid argument. Unrecognized selector sent to instance"
UIPanGestureRecognizer * panRec = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(handlePan:)];
panRec.delegate = self;
[panedView addGestureRecognizer:panRec];
UISwipeGestureRecognizer * swipeRec = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(handleSwipe:)];
swipeRec.direction = UISwipeGestureRecognizerDirectionUp;
swipeRec.delegate=self;
[panedView addGestureRecognizer:swipeRec];
[self gestureRecognizer:swipeRec shouldRequireFailureOfGestureRecognizer: panRec];
gestureRecognizer:shouldRequireFailureOfGestureRecognizer: is a delegate of the the UIGestureRecognizer. Meaning , you will implement the method , and when a gesture happens this method will be called automatically . To enable the gesture recognisers calling this method you need to set the gesture recogniser delegate to self, this can be done in viewDidLoad.
Simply I want to add a tap gesture for a UIImageView that when the user touches, calls a method that is implemented in another class (not the same class that contains the UIImageView).
Can I do this and if so how can i do it ?
You can do that. But you need the instance of the target class (class in which method is going to execute) as delegate or something in the gesture adding class.
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc]initWithTarget:self.delegate action:#selector(doSomething)];
Here delegate will be the instance of the target class that you have to set before going to that class.
Edit
I will explain a little more. Suppose you have two view controller classes VCA and VCB. you want to call a method in VCA from VCB through a tap gesture.
in VCB.h
#property (nonatomic,assign)VCA *delegate;
in VCB.m
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc]initWithTarget:self.delegate action:#selector(doSomething)];
in VCA.m
You will present/ push VCB
VCB * viewController = [[VCB alloc]init];
viewController.delegate = self;
// push or present viewController
Declare recognizer selector on init
UITapGestureRecognizer *recognizer =
[UITapGestureRecognizer
initWithTarget:objectOfAnotherClass
action:#selector(methodImplementedOnObjectOfAnotherClass:)];
dont forget about defining number of taps (numberOfTapsRequired) and optional gesture recognizer required to fail (requireGestureRecognizerToFail:)
Link to article about selector.
One straightforward approach is calling the method of another class from the selector method of tapGesture ie.
Add UITapGestureRecogniser to the imageview
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc]initWithTarget:self action:#selector(tapRecognised)];
[imageView addGestureRecognizer:tapGesture];
Dont forget to enable the userInteraction of the UIImageView, because by default for imageview userInteraction is disabled.
you can do this like below.
imageView.userInteractionEnabled = YES;
Then in the selector of tapGestureRecogniser call the method of another class
- (void)tapRecognised
{
[next tappedOnImage];
}
Here next is the object of another class. You can use delegation also to call the method.
Hope this will help you.
here self.desired view is the view in which you want to add gesture and you should add gesture in following way
and "webViewTapped.delegate = self" means you want to call a function of the same class when user tap and you can change it to your desired function by using delegate like self.delegate
UITapGestureRecognizer *viewTapped = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapAction:)];
webViewTapped.numberOfTapsRequired = 1;
webViewTapped.delegate = self;
[self.desiredView addGestureRecognizer:viewTapped];
- (void)tapAction:(UITapGestureRecognizer *)sender;
{
// do your stuff here
}
I have a simple program that does a calculation on a button press. The result is placed into a label using the following code:
//converts the float to 2 descimal places then converts it to a string
NSString *stringRectResult=[[NSString alloc]
initWithFormat:#"%1.2f",floatCalcResult];
//displays the string result in the label
resultLabel.text=stringRectResult;
It works perfectly, however, I added in code to hide the decimal keyboard when the user touches off the keyboard. That works, but when I added this code the button to update the label no longer worked. Can anyone help? The code to hide the keyboard is below. The app works when I comment it out but does not when it is active
In viewDidLoad:
UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc]
initWithTarget:self action:#selector(tap:)];
[self.view addGestureRecognizer:tapRecognizer];
Tap selector...
-(void)tap:(UIGestureRecognizer *)gr
{
[self.view endEditing:YES];
}
Thanks for any and all help.
The problem is that by intercepting all of the user's taps (in order to hide the keyboard), you're preventing any other user interface elements from being tapped. I would urge you to rethink your design; it's not usually necessary to have an explicit facility to hide the keyboard.
If you do want to keep this design, you can implement the gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer: method in your class:
- (void) viewDidLoad
{
// ...
UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc]
initWithTarget:self action:#selector(tap:)];
tapRecognizer.delegate = self;
[self.view addGestureRecognizer:tapRecognizer];
}
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer
shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
return YES;
}
Two things to keep in mind:
You need to mark your view controller as conforming to the UIGestureRecognizerDelegate protocol.
If you later add a second gesture recognizer to the view, you'll need to add a check inside the second method to treat the second recognizer differently.