The following code used to work in iOS6 to hide the keyboard when a view controller was popped off of the navigation stack:
- (void)viewWillDisappear:(BOOL)animated {
[self.view endEditing:YES];
[super viewWillDisappear:animated];
}
However, in iOS7, the [self.view endEditing:YES] line seems to get ignored. I tried the command in other view events (viewDidDisappear, viewWillAppear, and viewDidAppear), and the only one it worked in is viewDidAppear. It seems that once a "pop" is initiated, we lose the ability to hide the keyboard until the view controller is "pushed" back on the stack.
While placing the code in viewDidAppear does work to hide the keyboard, the bad thing is that the keyboard is displayed briefly when the viewController is pushed back on to the navigation stack...pretty unacceptable from a UI perspective.
Has anyone else had success in working around this issue? I would prefer not to have to write my own CANCEL button, but right now, that is the only thing I can think of that will work.
If it's a UITextView set the editable property to NO. I tried this and it hides the keyboard as soon as it's set. I haven't tried it with a UITextField but I'm guessing you'd get the same result with setting the enabled property to NO. If that doesn't work, create a UITextField with userInteractionEnabled set to NO as a background for a transparent UITextView and use the editable property as stated above.
There was a change in iOS 7 where view controllers that are presented as modal forms cannot dismiss the keyboard by default. To fix this, you need to override your view controller's disablesAutomaticKeyboardDismissal method and return NO.
The problem is that somewhere between the time I press the "BACK" button and the time that viewWillDisappear fires, the current text field's canResignFirstResponder is getting set to FALSE, which is preventing the keyboard from hiding. I have not been able to discover anything in my code which could cause this, and I strongly suspect that it could be some kind of iOS 7 bug, as the same code worked for me under iOS 6.
As a workaround, I implemented the following solution. I subclassed UINavigationController and overrode the following method:
- (UIViewController *)popViewControllerAnimated:(BOOL)animated {
[self.topViewController.view endEditing:YES];
return [super popViewControllerAnimated:animated];
}
This caused the keyboard to appropriately disappear when I tapped the Back button to pop the current view controller. Nice sigh of relief that I didn't have to write a bunch of custom Back buttons.
To hide the keyboard when the text field lost focus
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
if ([textField isFirstResponder])
[textField resignFirstResponder];
return YES;
}
I tried a workaround. It may not be what you guys are expecting.
If you are using storyboard, You can resign the keyboard in "prepareForSeuge" method.
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
[self.view endEditing:YES];
}
It worked fine for me.
Approach given in the below will definitely hide the status bar in iOS7.
- (BOOL)prefersStatusBarHidden
{
return YES;
}
Add this to your .plist file (go to 'info' in your application settings)
View controller-based status bar appearance --- NO
Then you can call this line to hide the status bar:
[[UIApplication sharedApplication] setStatusBarHidden:YES];
In case your app is developed to support iPhone only, status bar won't hide when you run your app in iPad.
Put your UItextfield or UItextview for global declaration.
UITextfield textfield = your textfield object;
-(void)viewWillDisappear:(BOOL)animated
{
[self.view endEditing:YES];
[textfield resignFirstResponder];
[super viewWillDisappear:animated];
}
Related
I have a view that is presented, but when I dismiss that same view, and try to edit a text field on the original view, I can see the flashing cursor in the text field, but the keyboard doesn't appear. Only calling this:
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[self.view endEditing:YES];
}
Note: this only seems to be an issue on the iPhone 4 running iOS 7, not sure if this indicates a bug or not. Thank you.
I've got a HomeViewController that has different modal segues to several other UIViewControllers. If I try to show the keyboard on a UITextField within the HomeView, everything works fine. However, if I try to show the keyboard on a UITextField (using becomeFirstResponder) after returning from any of the modal View Controllers, the keyboard never shows.
Here's some sample code from one of the setups I've tried:
In HomeViewController:
- (void)viewDidAppear:(BOOL)animated
{
static BOOL firstTimeComplete = false;
if (!firstTimeComplete) {
firstTimeComplete = true;
} else {
UITextField *textField = [[UITextField alloc] init];
[self.view addSubview:textField];
[textField performSelector:#selector(becomeFirstResponder) withObject:nil afterDelay:3]
}
}
In ModalViewController:
- (IBAction)done:(id)sender
{
[self dismissViewControllerAnimated:YES completion:nil];
}
Where done: is linked to the "Done" button via a touch up inside event.
A few things I've tried:
Converting the modal segues to push segues fixes the issue, but I don't want a Nav bar in any of the child views
I've tried disabling and enabling animations when dismissing the
modal view controller (using dismissViewControllerAnimated:)
Using unwind segues in the storyboard rather than doing it programmatically
Anyone have an idea of what may be going on?
After deleting tons of code, I finally found out that a custom NavigationController was being used and this was the root cause:
#implementation MSLNavigationController
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationPortrait;
}
- (BOOL)shouldAutorotate
{
return NO;
}
#end
The app doesn't need this code, so I've nuked the file. (But an explanation as to why this would be hiding the keyboard would be awesome :))
You did not call [super viewDidAppear:animated]
In place like that i have workaround that works pretty well
- (void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^
{
if (self.textView.text.isNotEmpty)
{
[self.textView becomeFirstResponder];
}
});
}
I have been struggling with this problem for some time, so I'll post here what I found out.
I was calling textField.becomeFirstResponder() in viewWillAppear but on iOS 7, after the modal was dismissed, the keyboard would not show again, even when you would tap on the textField.
For me calling textField.resignFirstResponder() when the modal is presented, solved the issue. It seems like the input field was already marked as first responder and then would not react to the new calls.
I have a view controller whose view is setup in such a way that it has 3 buttons and other subviews. On clicking one of the buttons(3rd button), i am adding another view controller's view as subview to self.view (in this view i have a search display controller in the active state with keyboard)
I'm able to achieve this using the following code
[self.searchDisplayController setActive:YES];
[self.searchDisplayController.searchBar setShowsCancelButton:NO];
[self.searchDisplayController.searchBar becomeFirstResponder];
Now when i press the 2nd button, i try removing this view from the superview and also try to resign the keyboard in the viewWillDisappear ([self.view endEditing:YES]) in the following manner, but keyboard still doesnt resign
One small edit, it is resigning in case i comment out the following piece of code
- (BOOL)searchBarShouldEndEditing:(UISearchBar *)searchBar {
if (self.dataSource.count)
return YES;
return NO;
}
Try to resign UISearchBar in viewWillDisappear
[yourSearchBar resignFirstResponder];
Inside the method that is called to your 2nd button, just type in
[self.searchDisplayController.searchBar resignFirstResponder];
Leave the viewWillDisappear alone. That is for when the view is done with whatever animation it is doing, and when the view is leaving. If you set the display controller to resigning the responder, it should make it go away immediately.
Hope this helps!
you can do it using NSNotificationCenter as below.
//.m file:
[[NSNotificationCenter defaultCenter]addObserver:self
selector:#selector(ResignFirstResponder:) name:#"resign" object:nil];
in ResignFirstResponder:
[searchBar resignFirstResponder];
in which class you use above addObserver, you have to implement that method.
//.m file from where you want to send action, call method as below. [on your second button click]
[[NSNotificationCenter defaultCenter] postNotificationName:#"resign"
object:nil];
So i am making an app and am having some problems with dismissing the keyboard from UISearchBar and UITextFields. Here is the structure of my app:
NavigationController -> ViewC1 - (Modally)-> ViewC2 -(Modally) -> ViewC3
I have a search box in ViewC1, and when the "Search" button on the keyboard is pressed the keyboard is dismissed, this works fine. However if i return to ViewC1 after being in ViewC3 the keyboard no longer dismisses when the "Search" button is pressed. In the search bar delegate method i have put as follows:
- (void) searchBarSearchButtonClicked:(UISearchBar *)search
{
if ([search isFirstResponder]) {
[search resignFirstResponder];
} else {
[search becomeFirstResponder];
[search resignFirstResponder];
}
}
This does not solve the problem and i am not sure why the keyboard is not dismissing. For reference, when returning to the original ViewC1, ViewC3 is dismissed as follows:
UIViewController *parent = self.presentingViewController;
[parent.presentingViewController dismissViewControllerAnimated:YES completion:nil];
Any help is appreciated, thanks.
Okay i figured out what the problem was. They first responder was being resigned but the keyboard was not disappearing because of a focus issue. There is a default behaviour on modal views to not dismiss the keyboard (which is not a bug apparently). So after returning from the modal view it was still having this behaviour (resigning first responder but not dismissing keyboard). The way i solved this was by placing the following code in both the modal views .m files:
- (BOOL)disablesAutomaticKeyboardDismissal {
return NO;
}
This solved it for me. Then by either using:
[search resignFirstResponder];
or
[self.view endEditing: YES];
The keyboard will dismiss fine!
You'll need to do some debugging with break points to figure out why that conditional statement is not being hit. You could also use the endEditing method in UIView to simply resign the responder whenever search is clicked:
- (void) searchBarSearchButtonClicked:(UISearchBar *)search
[search endEditing:YES];
}
http://developer.apple.com/library/ios/#documentation/UIKit/Reference/UIView_Class/UIView/UIView.html
Try it....
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar
{
[mySearchBar resignFirstResponder];
}
Please declare IBOutlet UISearchBar *mySearchBar; in your .h file
Set delegate in your .xib file.
Hope this helped
(A year later..)
I've just had the same problem with my iPad app.
I had a"Please register" UIView containing a few UITextFields which I would pop onto the screen. When the user tapped on a Close button, it'd disappear, and I'd use removeFromParentViewController to get rid of it.
[self.pleaseRegisterDlg removeFromParentViewController];
Now, when I ran this code on a real device in debugging mode from XCode, the story ended there. It all worked fine. But when I built an In-House app with this code, it behaved differently.
I would find that sometimes, no matter how many resignFirstResponders or disablesAutomaticKeyboardDismissals I put into the code, there would be times when the onscreen keyboard would suddenly appear, and refuse to go away programatically.
It made no sense, as the rest of my app didn't have any UITextFields... there was no reason for the app to display a keyboard.
My solution was to set the "Please Register" UIView to nil after removing it from the parent view.
[self.pleaseRegisterDlg removeFromParentViewController];
pleaseRegisterDlg = nil;
Apparently, having a UIView which isn't actually attached to any other UIViews but which contains UITextFields is sometimes enough to confuse iOS, and make the onscreen keyboard appear.
(Sigh. This one line of code wasted a few hours of my afternoon.. lesson learned !)
My keyboard appears with a textView, I want to hide it when the user push on a back button on a navigation bar.
I have tried this:
-(void)viewWillDisappear:(BOOL)animated{
[myTextView resignFirstResponder];
}
and this:
-(void)viewDidDisappear:(BOOL)animated{
[myTextView resignFirstResponder];
}
But it doesn't work, how can I do this?
edit:
I found the solution here:
iPad keyboard will not dismiss if modal ViewController presentation style is UIModalPresentationFormSheet
Put this into the buttonPress method -
[self.view.window endEditing:YES];
Edit - this also lets you get the contents of the text being edited when the "back" button is pressed
Combining the above answers and checking for back button will be done by this
- (void)viewWillDisappear:(BOOL)animated{
if ([self.navigationController.viewControllers indexOfObject:self]==NSNotFound) {
// back button was pressed. We know this is true because self is no longer
// in the navigation stack.
[self.view.window endEditing:YES];
}
[super viewWillDisappear:animated];
}