I have created one scrollview for registration. I have also use tableview for drop-down(Male/Female) and tap Gesture on scrollview for hide all input views because touchesBegan method dose not call. whenever i click on table view cell,it will not call didselect method but consider as tap on scrollview.
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(dismissKeyboard)];
tap.numberOfTapsRequired=1;
[_scrollview_out addGestureRecognizer:tap];
Method:-
-(void)dismissKeyboard
{
[_txt_name resignFirstResponder];
[_txt_mname resignFirstResponder];
[_txt_surname resignFirstResponder];
[_txt_gender resignFirstResponder];
[_txt_dob resignFirstResponder];
_tbl_view_gender.hidden=true;
_txt_dob.hidden=false;
_lbl_dob.hidden=false;
}
Table View didSelect Method:-
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[_scrollview_out endEditing:YES];
str2=[gender_arr objectAtIndex:indexPath.row];
_txt_gender.text=str2;
_tbl_view_gender.hidden=true;
_txt_dob.hidden=false;
_lbl_dob.hidden=false;
}
for me there are two options:
1: add the tableview in scrollView's superView
2: subclass UIScrollView, overwrite method:
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
//if the touch point in the tableview.
//return NO;
//else
//return YES;
}
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
if ([touch.view isDescendantOfView:Your Tableview]]) {
// Don't let selections of auto-complete entries fire the
// gesture recognizer
return NO;
}
return YES;
}
Related
I have a UIWebView in my UITableView cell. However when I scroll the UIWebView, UITableView scrolls too. How do I make sure only one UIWebView scrolls when the user tries to scroll it?
This Question has not been answered yet so i am posting my answer so
late .
I had the same problem , i solved with creating custom Delegate. follow the steps below.
1. Create Custom delegate in your UITableViewCell
#protocol MyTableCellDelegate <NSObject>
-(void)webViewDidStartedScrolling;
-(void)webViewDidStoppedScrolling;
#end
2. Add UIScrollViewDelegate in your TableCell.h file
#interface TableCell : UITableViewCell<UIWebViewDelegate,UIScrollViewDelegate>
property(weak,nonatomic) id<MyTableCellDelegate> delegateWebView;
3. in your TableCell.m file
- (void)awakeFromNib {
[super awakeFromNib];
self.myWebView.scrollView.delegate=self;
}
//ScrollView delegate method
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
if(self.delegateWebView && [self.delegateWebView respondsToSelector:#selector(webViewDidStoppedScrolling)]){
[self.delegateWebView webViewDidStoppedScrolling];
}
}
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
if(self.delegateWebView && [self.delegateWebView respondsToSelector:#selector(webViewDidStartedScrolling)]){
[self.delegateWebView webViewDidStartedScrolling];
}
}
4. add MyTableCellDelegate in your UIViewController.h where you are having Your table View.
#interface UIViewController ()<UITableViewDelegate,UITableViewDataSource,MyTableCellDelegate>
5. Implement the methods of your custom delegate methods in your UIViewController.m file , and enable or disable tableView scrolling , when your webviewDidEndScrolling and webviewDidStartedScrolling
#pragma mark UItableView Delegate
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
YourTableCell *cell=[tableView dequeueReusableCellWithIdentifier:#"YourTableCell" forIndexPath:indexPath];
cell.delegateDealDetails=self;
}
// Custom Delegate Callback method
-(void)webViewDidStartedScrolling
{
tblDealDetails.scrollEnabled=NO;
}
-(void)webViewDidStoppedScrolling
{
tblDealDetails.scrollEnabled=YES;
}
This works fine for me , i hope this will help others who is facing same problem.
You can use an disable and enable scroll of the tableView, when the webView scroll delegate is called.
UIWebView has a scrollView inside, that you can be I'ts delegate.
- (void)setupSwip
{
UISwipeGestureRecognizer* swipeGesture = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(didSwip:)];
swipeGesture.delegate = self;
[self.view addGestureRecognizer:swipeGesture];
self.tableView.scrollEnabled = YES
}
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
self.tableView.scrollEnabled = NO;
return YES;
}
- (void)didSwip:(UIGestureRecognizer*)gestureRecognizer
{
}
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
self.tableView.scrollEnabled = NO;
}
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
if (!decelerate)
{
self.tableView.scrollEnabled = YES;
}
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
self.tableView.scrollEnabled = YES;
}
I am trying to using UIPanGestureRecognizer and UITapGestureRecognizer on UISlider. tap is working fine i am facing problem with UIPanGestureRecognizer. I need to call handleTransactionPan method on changing value of UISlider but it is never being called because of its delegate method.
How can i invoke the selector while keeping the delegate methods to fire? Here is the code for what i have done so far.
- (void)viewDidLoad
{
[super viewDidLoad];
pr=[[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(handleTransactionPan:)];
pr.delegate=self;
[slider addGestureRecognizer:pr];
tr=[[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleTap:)];
tr.delegate=self;
[slider addGestureRecognizer:tr];
}
-(BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
return YES;
}
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
return YES;
}
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
if(gestureRecognizer==pr)
{
if ([touch.view isKindOfClass:[UISlider class]]) {
return NO;
}
}
return YES;
}
I am using :
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]
initWithTarget:self
action:#selector(dismissKeyboard:)];
[self.view addGestureRecognizer:tap];
in order to close keyboard when clicked anywhere else from UITextField.
However in my view, I have UITableView , and I have to detect when click on the rows of UITableView.
Because of UITapGestureRecognizer my didSelectRowAtIndexPath function is not called. Is there any way to detect whether the clicked object is UITableViewCell?
You can get thouch event of Gesture from
- (BOOL) gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
you detect touch of gesture so do logically like bellow:
- (BOOL) gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
if ([touch.view isKindOfClass:[UITextFiled class]])
{
return FALSE;
}
else
{
// here is remove keyBoard code
return TRUE;
}
}
Implement this delegate method gestureRecognizerShouldBegin:, check and cancel your gesture callback which happen on tableview cell(row) and trigger tableview's delegate method.
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
if ([gestureRecognizer.view isKindOfClass:[UITableViewCell class]])
{
return NO;
}
return YES
}
I'm using UITapGestureRecognizer to end editing (because that's the workaround I found useful to end editing on input keyboards that have no other way to do so, like the Decimal Pad). The problem is that inside that viewController I have a tableView (the UITableViewDataSource and UITableViewDelegate of that tableView are set to the viewController) and the method didSelectRowAtIndexPath is not being triggered.
Code:
viewDidLoad {
...
UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tap:)];
[self.view addGestureRecognizer:tapRecognizer];
...
}
- (void)tap:(UIGestureRecognizer*)gr {
[self.view endEditing:YES];
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(#"Help!");
}
I know the UITapGestureRecognizer is catching the selection, because if I comment out as following:
viewDidLoad {
...
UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tap:)];
//[self.view addGestureRecognizer:tapRecognizer];
...
}
now the method the didSelectRowAtIndexPath finally triggers out.
I need help with some good practices on how to workaround the "endEditing" or how to forward the tap gesture to the tableView so that the didSelectRowAtIndexPath triggers out.
Thanks!
I assume that you haven't a tableView that takes all the screen, otherwise you can close the keyboard in didSelectRowAtIndexPath.
Any way, you can do your stuff and the pass the event to the next responder (that is kind of class UITableViewCell if there is, so if user tap on the tableView):
- (void)tap:(UIGestureRecognizer*)gr {
[self.view endEditing:YES];
UIResponder *responder = self;
while (responder.nextResponder != nil){
responder = responder.nextResponder;
if ([responder isKindOfClass:[UITableViewCell class]]) {
break;
}
}
[responder touchesBegan:touches withEvent:event];
}
I am new in iOS development. I want to hide the keyboard when tapping outside of a UITextView.
My TextView is in a cell from an UITableView. The problem is that I have a Toolbar at the top and my buttons doesn't react anymore. I implemented the method "shouldReceiveTouch" but my test is not correct i think. Any ideas? Thank you and sorry for my bad english..
In my ViewDidLoad:
tap = [[UITapGestureRecognizer alloc]
initWithTarget:self
action:#selector(dismissKeyboard)];
tap.delegate = self;
[self.view addGestureRecognizer:tap];
note: tap is an UITapGestureRecognizer property.
Implemented methods:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer
shouldReceiveTouch:(UITouch *)touch {
if ([touch.view isKindOfClass:[UIBarButtonItem class]]) {
return NO;
}
return YES;
}
-(void)dismissKeyboard {
[tview resignFirstResponder];
}
UIBarButtonItem is not a subclass of UIView, hence the shouldReceiveTouch still return YES.
Try to exclude the whole UIToolbar or just add the tap gesture recognizer in the UITableViewCell when you initialize the cell in cellForRowAtIndexPath.
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer
shouldReceiveTouch:(UITouch *)touch {
if ([touch.view isKindOfClass:[UIToolbar class]]) {
return NO;
}
return YES;
}
You should add your gesture to table view.
tap = [[UITapGestureRecognizer alloc]
initWithTarget:self
action:#selector(dismissKeyboard)];
tap.delegate = self;
[tblView addGestureRecognizer:tap];
use didScroll method of UIScrollView delegate to resign keyboard.TableView is also subclass of UIScrollView so it should work.
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
[tview resignFirstResponder];
}
or use this one
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
[tview resignFirstResponder];
}
If you still want to use gesture then add gesture to UIView or self.view or superView of tableView
instead of adding it to tableView
Try following code :----
Keep you code as it is and add this method
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[tview resignFirstResponder];
}
in viewDidLoad set self.view.userInteractionEnabled = yes;
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [[event allTouches] anyObject];
if ([touch view] == tview) {
[tview resignFirstResponder];
}
}