I use UITapGestureRecognizer on a tableView for -endEditing after -textFieldDidBeginEditing. First I want to make -endEditing and then perform this touch on tableView's element. How can I do it right way?
#pragma mark - Text Field Delegate
- (void)textFieldDidBeginEditing:(UITextField *)textField {
UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(finishEditing:)];
[self.tableView addGestureRecognizer:tapRecognizer];
}
- (void)finishEditing:(UITapGestureRecognizer *)tapRecognizer {
[self.view endEditing:YES];
}
- (void)textFieldDidEndEditing:(UITextField *)textField {
[self saveName];
}
Setting cancelsTouchesInView to false will pass the touches through to the view.
When this property is true (the default) and the receiver recognizes
its gesture, the touches of that gesture that are pending are not
delivered to the view and previously delivered touches are cancelled
through a touchesCancelled:withEvent: message sent to the view. If a
gesture recognizer doesn’t recognize its gesture or if the value of
this property is false, the view receives all touches in the
multi-touch sequence.
See the reference here
Related
I am trying to remove the keyboard when it is in editing mode of a textview.I have added tap gesture on the main view.But on the click of when editing mode is for textfield then keyboard is removed but when editing mode is for textview then keyboard is not removed.Please tell me how can i tackle this issue?
added tap gesture to the main view.
UITapGestureRecognizer *singleFingerTap =
[[UITapGestureRecognizer alloc] initWithTarget:self
action:#selector(handleSingleTap:)];
[self.main_view setUserInteractionEnabled:true];
[self.main_view addGestureRecognizer:singleFingerTap];
calling method
- (void)handleSingleTap:(UITapGestureRecognizer *)recognizer
{
if([self.txt_username isFirstResponder])
{
[self.txt_username resignFirstResponder];
}
if([self.txt_password isFirstResponder])
{
[self.txt_password resignFirstResponder];
}
}
I have already set the delegate for text view & also i have added the textview protocol.
delete code for set setUserInteractionEnabled =true , u not need that
and add this in your func
-(void)handleSingleTap:(UITapGestureRecognizer *)recognizer
{
[self.view endEditing:YES];
}
or u can use library TPKeyboardAvoiding , set for scrollview..its automatic close keyboard when u tap view..so u not need that UITapGestureRecognizer
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
[[self view] endEditing:YES];
}
When there are new or changed touches for a given phase, the app object calls one of these methods. Each method takes two parameters: a set of touches and an event.
For more info Click here
i think you just put only textview resingFirstresponder.
- (void)handleSingleTap:(UITapGestureRecognizer *)recognizer
{
[self.txt_username resignFirstResponder];
}
use it.
I am trying to handle tableViewCell's being tapped, but the problem is that this is a "temporary tableView". I have it coded so that it will appear while the user is editing a UITextField, but then I set up a gesture recognizer to set the tableview to hidden as soon as the user clicks somewhere away from the UITextField.
I have the gesture recognizer set up as follows:
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]
initWithTarget:self
action:#selector(dismissKeyboard)];
[tap setCancelsTouchesInView:NO];
[self.view addGestureRecognizer:tap];
However, dismissKeyboard is called before didSelectRowAtIndexPath is called, and so the TableView that I want to handle the event on becomes hidden and therefore this function is never called.
My question is: Does anybody have ideas of how to get around this, so that didSelectRowAtIndexPath will execute before the tableView hides? I had one idea to somehow see if the tableView is where the tap is coming from, and if so, then don't execute the "hide tableView" line within dismissKeyboard. Is this possible?
Sorry, but I am new to iOS dev, so thank you for any advice!
You should be able to do this by making your view controller the tap gesture's delegate and denying it any touches that are inside the table view. Here is a starting point:
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gesture shouldReceiveTouch:(UITouch *)touch
{
//Assuming your table view is a direct subview of the gesture recognizer's view
BOOL isInsideTableView = CGRectContainsPoint(tableView.frame, [touch locationInView:gesture.view])
if (isInsideTableView)
return NO;
return YES;
}
Hope this helps!
You could set yourself as a delegate to the UITapGestureRecognizer and cancel the gesture when the user taps within the tableView.
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
//You can also (and should) check to make sure the gestureRecognizer is the tapGestureRecognizer
if (touch.view == tableView)
{
return NO;
}
else
{
return YES;
}
}
To better fit what you need, judge if your search bar is first responder.
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gesture shouldReceiveTouch:(UITouch *)touch
{
BOOL isInsideTableView = CGRectContainsPoint(yourTabelView.frame, [touch locationInView:gesture.view]);
if (isInsideTableView && ![yourSearchBar isFirstResponder])
return NO;
return YES;
}
I have a button, it works as usual on iOS 5 and 6. But on iOS 7 when I press the button the keyboard dismisses, but the method is not called. When I press it second time it works as intended.
Why is that?
Here is the code:
[self.loginButton addTarget:self action:#selector(loginButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
I have the button in UITableView cell.
EDIT:
Here is how I dismiss keyboard at the beginning of this method, but this method is not getting called o iOS7 until the second time I tap on the button.
for (UITextField *field in #[self.loginField, self.passwordField]) {
if ([field isFirstResponder]) {
[field resignFirstResponder];
}
}
I also have gesture recognizer to remove keyboard on tap outside:
UITapGestureRecognizer *tapper = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(removeKeyboard)];
[self.view addGestureRecognizer:tapper];
tapper.cancelsTouchesInView = NO;
Here is its method:
- (void) removeKeyboard
{
[self traverseAllSubviewsOfView:self.view withBlock:^(UIView *inView) {
[inView resignFirstResponder];
}];
}
Here is what helped me - I set controller as delegate for gesture recognizer and implement following method:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
// test if touch is on button
if ([touch.view isKindOfClass:[UIControl class]]) {
return NO;
}
return YES; // handle the touch
}
Did you check the cancelsTouchesInView property of the gesture recognizer? This property controls if touches are delivered to any underlying views. So settings this to NO should allow the touch to be sent to your button. More detail here.
This property can be set in code or in Interface Builder. You can set it in IB by highlighting the gesture recognizer and uncheck "Cancels Touches in View" (I think) in the Attributes Inspector.
I'm not in front of a Mac currently so I can't confirm the exact wording.
What I'm working with is I have a custom UIView that combines a UILabel with a UITextField as part of some user input. I have several of these throughout the view that is being displayed in the app. What would be good is to be able to have the user touch either the UILabel or the UITextField and then have the UITextField allow for input of the field.
Is there an easy way to do this?
Add a tap gesture recognizer to your label, and when tapped tell the corresponding textfield to become first responder (which brings up the keyboard).
// In your init or awakeFromNib:
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(labelTapped:)];
self.label.userInteractionEnabled = YES;
[self.label addGestureRecognizer:tap];
...
- (void)labelTapped:(id)sender
{
[self.textField becomeFirstResponder];
}
Yes, there is and I actually tested it. You can add a tap gesture recognizer to your view (the one that contains the label and the text view) like so:
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(viewTapped:)];
[self addGestureRecognizer:[tap autorelease]];
and then, inside viewTapped:
-(void)viewTapped:(id)sender {
[self.yourTextField becomeFirstResponder];
}
Hope this helps!
You can define UIGestureRecognizer delegate method and check that is the the required tap gesture area . If it is then return TRUE else return FALSE .
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
// Disallow recognition of tap gestures in the segmented control.
if ((touch.view == yourButton)) {//change it to your condition
return NO;
}
return YES;
}
I have a UITableView with an associated UITableViewController. However, I've modified the table to also have a view with a textfield subview.
As always, I want the keyboard to disappear when the user hits 'done' (easy) and when they touch anywhere else on screen other than the textfield (hard, stuck!).
The normal way to achieve this is to change the class to UIControl so it can handle actions... but I can't do this for my UITableView/UITableViewController combination.
How can I solve this problem?
U can handle user touches by adding a UITapGestureRecognizer to your view.
For example if u don't want to enable row selection in your tableView u call self.tableView.allowsSelection = NO;
But if u still want to detect user touches u add a UITapGestureRecognizer to your tableView (or to tableView.superview).
U can have more control if u implement the UIGestureRecognizerDelegate, this way u can detect and then choose witch touches to receive and witch not.
To do that just add this code to your UITableViewController:
- (void)viewDidLoad
{
[super viewDidLoad];
self.tableView.allowsSelection = NO;
UITapGestureRecognizer *tgr = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(viewTapped:)];
tgr.delegate = self;
[self.tableView addGestureRecognizer:tgr]; // or [self.view addGestureRecognizer:tgr];
[tgr release];
}
- (void)viewTapped:(UITapGestureRecognizer *)tgr
{
NSLog(#"view tapped");
// remove keyboard
}
// this is optional, it let u choose witch touches to receive, for example here I'm checking if user has tapped on a textField
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
if ([touch.view isKindOfClass:[UITextField class]]) {
NSLog(#"User tapped on UITextField");
}
return YES; // do whatever u want here
}
A normal practice is to put a custom UIButton( it becomes visible only when uitextfield begins editing ) behind keyboard view, and when user clicks on screen he actually clicks on that button, and associated selector can resign first responder.
-(void) closeKeyboard:(UIButton *) b {
[self.view endEditing:YES]; //assuming self is your top view controller.
[b setHidden:YES];
}
Using endEditing is better, cause it loops through all subviews and looks for current first responder.
Using alloc breaks with ARC enabled
Just add the following to the viewController
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
//where text field is a #property (nonatomic,retain) IBOutlet to your textfield
[textField resignFirstResponder];
}
When a row is tapped the didSelectRowAtIndexPath is called. If a textField located inside inside a row is tapped then the textfield delegate is called.
So in addition to your done button method, in didSelectRowAtIndexPath add a check for the text field being first responder and ask it to resign. Assuming a the selected indexPath is not the row of the textfield.