I am reloading my table with reloaddata on rotation of device in my app. If a UITextfield is focused before rotation and keyboard is open , I want it to stay focused and keyboard remains open. Reloaddata calls "textfieldshouldEndEditing" and "KeyboardshouldHide" notifications and thus on rotation my textfield is not focused and keyboard is also closed.
To achieve this I am using the following code:
[myTextfield performSelector:#selector(becomeFirstResponder)
withObject:nil
afterDelay:1.0f];
This works fine and keyboard opens again after rotating the device but the problem is when I press keyboard hide button (now keyboard is closed) and then rotate the device, Keyboard is still showing up which is wrong as before rotating the device I closed it.
Can someone suggest what is wrong or what should be done to achieve this? Thanks
How about just using a BOOL class variable like this:
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
hasKeyboardOpen = YES;
}
// your own method to hide keyboard you would call when user physically hide keyboard
- (void)dismissKeyboard
{
[myTextField resignFirstResponder];
hasKeyboardOpen = NO;
}
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
if(hasKeybaordOpen == YES)
{
[myTextfield performSelector:#selector(becomeFirstResponder)
withObject:nil
afterDelay:1.0f];
}
}
So you before the rotation if the keyboard is visible you it and schedule it to present in 1 second.
I guess the problem is that you schedule the keyboard to present even if it is hidden. If that is the case you should check if the keyboard is visible before performSelector: withObject:afterDelay:
if ([myTextField isFirstResponder]) {
[myTextField resignFirstResponder];
[myTextField performSelector:#selector(becomeFirstResponder) withObject:nil afterDelay:1.];
}
Although I really don't think performSelector: withObject:afterDelay: is the proper way of doing it. You might want to use willRotateToInterfaceOrientation:duration: and didRotateFromInterfaceOrientation: methods instead. You can store the reference to the textField or any other firstResponder (i.e. if you have multiple textFields or textViews:
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
if ([self.myTextFiled isFirstResponder]) {
self.toBeFirstResponderAfterInterfaceOrientationChange = self.myTextFiled;
[self.myTextFiled resignFirstResponder];
}
}
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
if (self.toBeFirstResponderAfterInterfaceOrientationChange) {
[self.toBeFirstResponderAfterInterfaceOrientationChange becomeFirstResponder];
self.toBeFirstResponderAfterInterfaceOrientationChange = nil;
}
}
- (void)textFieldDidEndEditing:(UITextField *)textField
{
self.toBeFirstResponderAfterInterfaceOrientationChange = nil;
}
Related
I am calling becomeFirstResponder, and showing the keyboard with it.
[inputTextField becomeFirstResponder];
However, it shows the custom keyboard that is installed on test device. Is there a way to show iOS Standard Keyboard for Number Pad?
From the answer list originally at: Prevent custom keyboard in textfield
- (BOOL)application:(UIApplication *)application shouldAllowExtensionPointIdentifier:(NSString *)extensionPointIdentifier {
if ([extensionPointIdentifier isEqualToString: UIApplicationKeyboardExtensionPointIdentifier]) {
return NO;
}
return YES;
}
I have set this UIViewController to be the delegate for the UITextField in the viewDidLoad with this line: self.nameInputTextField.delegate = self;.
I have set the delegate on the class as well by adding <UITextFieldDelegate> to the #interface declaration.
When I select the nextButton, in the method that is called, I have tried [self.nameInputTextField resignFirstResponder] as well as [self.view endEditing:YES] one line before I push the new view controller.
The rest of the class does not manipulate the firstResponder.
I've also implemented the UITextField delegate method
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
[self.nameInputTextField resignFirstResponder];
return NO;
}
I haven't found any related questions after extensive searching. There are many similar ones about resigning keyboards, but not regarding the timing of the keyboard resignation being postponed until after the view transition is complete. Note- if you reload this url in your browser, you'll see the gif again from the beginning.
Hide keyboard anywhere in ios :
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
for (UIView * txt in self.view.subviews){
if ([txt isKindOfClass:[UITextField class]] && [txt isFirstResponder]) {
[txt resignFirstResponder];
}
}
}
OR
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[self.view endEditing:YES];
}
Resign your keyboard on viewWillDisappear and the problem should be solved.
Edit
-(void)viewWillDisappear:(BOOL)animated{
[super viewWillDisappear:animated];
self.nameInputTextField.text = #"";
[self.nameInputTextField resignFirstResponder];
}
I have an app which involves using different kinds of Gestures. So, in order to differentiate between thse gestures, I used shouldRecognizeSimultaneouslyWithGestureRecognizer method which returns a YES. However, on doing this the keyboard on the UIWebView is dismissed right after it is being presented. And if I don't then the keyboard functions correctly but the controller fails to recognize different gestures.
How do I make the keyboard function correctly and at the same time recognize different gestures ?
Try this one
#pragma mark -
#pragma mark UITextFieldDelegate Methods
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
[textField resignFirstResponder];
return YES;
}
- (void)textFieldDidEndEditing:(UITextField *)textField {
[textField resignFirstResponder];
}
//You can use like this in your shouldRecognizeSimultaneouslyWithGestureRecognizer method
[textView resignFirstResponder];
In our app, there's a situation where the user enters something in a textbox and then presses the back button to go back to the master screen.
If we run that on iOS 7, the keyboard does not disappear, it just stays there. The user can still navigate through the app, but all text fields are disabled, meaning you can't enter text anywhere. The only option the user has is killing the app and starting fresh.
We tried to add resignFirstResponder messages, but that didn't help anything.
There's much code involved, and we're actively working on the issue. Meantime, has anyone experienced that problem too, and maybe found a way to make it go away?
I had the same issue like you when I compiled the app for iOS 7 and I did the following changes:
Make sure you add [textfield resignFirstResponder] before dismissing the viewController for example:
[_passwordInput resignFirstResponder];
[_emailInput resignFirstResponder];
[self performSegueWithIdentifier:#"forgotPassword" sender:self];
Just to be sure the keyboard disappears add [textfield resignFirstResponder] in viewWillDisappear for example :
- (void) viewWillDisappear:(BOOL)animated
{
[_passwordInput resignFirstResponder];
[_emailInput resignFirstResponder];
}
If your viewController is presented using UIModalPresentationFormSheet add this to your viewController just to make sure the textfields will respond resignFirstResponder:
- (BOOL)disablesAutomaticKeyboardDismissal
{
return NO;
}
In your case, override the back button action or just use viewWillDisappear to check when the user pressed the back button and then call resignFirstResponder before [super viewWillDisappear] something like this:
-(void) viewWillDisappear:(BOOL)animated
{
[_passwordInput resignFirstResponder];
[_emailInput resignFirstResponder];
[super viewWillDisappear:animated];
}
Try [self.view resignFirstResponder], instead of [textfield resignFirstResponder] on viewWillDisappear.
[textfield resignFirstResponder] should do the job, but to make sure and for not to loop through all your textFields you can use:
[self.view endEditing:YES];
From the doc:
use to make the view or any subview that is the first responder resign
(optionally force).
in general I find this useful
[[UIApplication sharedApplication] sendAction:#selector(resignFirstResponder) to:nil from:nil forEvent:nil];
you can add this in viewWillDisappear: or viewDidDisappear:
this will hide the keyboard without a reference to the currently focused text field
I had the same problem only with MoreViewController in UITabBarController (iOS 8.3). Maybe this solution not very 'nice' and little complicated, but seems like it works, hope it will help you too.
#interface ViewController ()
#property (nonatomic) BOOL needToHideKeyboard;
#property (nonatomic, strong) IBOutlet UITextField *txtField;
#property (nonatomic, strong) IBOutlet UIScrollView *scrollView;
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWasShown:) name:UIKeyboardDidShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillBeHidden:) name:UIKeyboardWillHideNotification object:nil];
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
self.needToHideKeyboard = NO;
}
- (void)viewWillLayoutSubviews
{
[super viewWillLayoutSubviews];
[self hideKeayboard];
}
- (void)hideKeayboard
{
if (self.needToHideKeyboard) {
[self.txtField resignFirstResponder];
}
}
- (void)keyboardWasShown:(NSNotification *)notification
{
self.needToHideKeyboard = YES;
NSDictionary *info = [notification userInfo];
CGSize keyboardSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
// Shift scroll view content insets on the keyboard height
UIEdgeInsets contentInsets = self.scrollView.contentInset;
contentInsets.bottom = keyboardSize.height;
self.scrollView.contentInset = contentInsets;
}
- (void)keyboardWillBeHidden:(NSNotification *)notification
{
self.needToHideKeyboard = NO;
// Reset keyboard content insets
UIEdgeInsets contentInsets = self.scrollView.contentInset;
contentInsets.bottom = [self.bottomLayoutGuide length];
self.scrollView.contentInset = contentInsets;
}
#end
If your view controller implements textFieldDidEndEditing, make sure you don't set another view to be the first responder if the view is disappearing. textFieldDidEndEditing will get invoked when you call resignFirstResponder, or [self.view endEditing:YES].
[self.view endEditing:YES];
stopped working on my device iOS9.x
We can also do this in the viewWillDisappear method
for (UIView *subview in self.view.subviews) {
if ([subview canPerformAction:#selector(endEditing:) withSender:nil]) {
[subview endEditing:YES];
}
if ([subview canResignFirstResponder]) {
[subview resignFirstResponder];
}
}
This will loop through the responders and resign the responder status.
How to hide the keyboard programmatically in iphone?
Tell the UIResponder subclass that is currently first responder to resign its first responder status:
[responder resignFirstResponder];
[textFieldName resignFirstResponder];
It's easy:
ObjC
[[[UIApplication sharedApplication] keyWindow] endEditing:YES];
Swift
UIApplication.shared.keyWindow?.endEditing(true)
take a look at UIView Class Reference for endEditing.
Causes the view (or one of its embedded text fields) to resign the first responder status. And keyWindow is the only window that receives keyboard events, so this solution is guarantied to always work.
Call this in your ViewController
[self.view endEditing:YES];
If you are using textview then
- (BOOL)textView:(UITextView *)textView
shouldChangeTextInRange:(NSRange)range
replacementText:(NSString *)text
{
if ([text isEqualToString:#"\n"])
{
[textView resignFirstResponder];
[self keyboardWillHide];
}
}
and if you are using textfield then
-(BOOL)textFieldShouldReturn:(UITextField*)textField;
{
[textField resignFirstResponder];
}
Here is the swift version:
UIApplication.sharedApplication().sendAction("resignFirstResponder", to:nil, from:nil, forEvent:nil)