i am working on a login screen which contain a scroll view and on the scrollview there are two text fields with a login button.
scrollview used to adjust for the iphone 5 screen size. and i am using a "tab gesture" so the if any user is entering text in text field and want to hide keyboard then can click on anywhere on the screen to hide key board. function used for the tab gesture is
- (void)viewDidLoad {
NSLog(#"login view");
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(singleTapGestureCaptured:)];
[self.scrollView addGestureRecognizer:singleTap]; }
- (void)singleTapGestureCaptured:(UITapGestureRecognizer *)gesture
{
[self.view endEditing:YES]; }
My problem is that when a user is entering text in the textfields using keyboard then in the middle of entering text keyboard detects the tab gesture and hides the keyboard in the middle.
what i did to solve the issue:-
1.) i changed the [self.view addGestureRecognizer:singleTap];
2.) i placed a view on the top of the screen with dimention (0,0,360,400) and apply the gesture to this view so that click on this view will hide keyboard but still when user types keyboard hide by calling gesture method
3.) i also used a button on the scrollview of half of screen size so taht user can click anywhere to hide the keybaord butsill while typing even then keyboard hides y calling the ibaction method of button palced
Remove Tapgesture And try this code , it will be helpful.
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
[self.view endEditing:YES];
}
Use This to hide the keyboard and show the keyboard:-
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
if (textField == username)
{
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillShow:) name:UIKeyboardDidShowNotification object:nil];
}
if (textField == password)
{
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillShow:) name:UIKeyboardDidShowNotification object:nil];
}
return YES;
}
- (BOOL)textFieldShouldEndEditing:(UITextField *)textField
{
if (textField == username)
{
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillHide:) name:UIKeyboardDidHideNotification object:nil];
}
if (textField == password)
{
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillHide:) name:UIKeyboardDidShowNotification object:nil];
}
return YES;
}
- (void)keyboardWillShow:(NSNotification *)notification
{
CGSize keyboardSize = [[[notification userInfo] objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
float newVerticalPosition = -keyboardSize.height + 100;
[self moveFrameToVerticalPosition:newVerticalPosition forDuration:0.3f];
}
- (void)keyboardWillHide:(NSNotification *)notification
{
CGFloat kNavBarHeight = self.navigationController.navigationBar.frame.size.height;
[self moveFrameToVerticalPosition:kNavBarHeight forDuration:0.3f];
}
- (void)moveFrameToVerticalPosition:(float)position forDuration:(float)duration
{
CGRect frame = self.view.frame;
frame.origin.y = position;
[UIView animateWithDuration:duration animations:^{
self.view.frame = frame;
}];
}
I found the best solution for it. First you integrate the pod 'TPKeyboardAvoiding', '~>1.2.3' and just add the TPKeyboardAvoidingScrollView Class. It will handle all.don't have to write extra code.
try like this,
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
[textField1 resignFirstResponder];
[textField2 resignFirstResponder];
}
hope this will help :)
Related
I want to move UITextField up above keyboard when user clicks UITextField.
I searched about this and some suggestion are to move whole view up and some suggestion are add scrollview.
But I don't want to use scrollview.
How can I do this?
Give your UITextField bottom Constant and when you found keyboard height in keyboardWillShow increase your UITextField bottom constraint to KeyboardHeight.
Just Put below code in ViewWillAppear.
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWillShow:)
name:UIKeyboardWillShowNotification
object:nil];
And put below code in ViewWillDisappear.
[[NSNotificationCenter defaultCenter] removeObserver:self
name:UIKeyboardWillShowNotification
object:nil];
Method
- (void)keyboardWillShow:(NSNotification *)notification
{
// Get the size of the keyboard.
CGSize keyboardSize = [[[notification userInfo] objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
int keyboardHeight = MIN(keyboardSize.height,keyboardSize.width);
textBottom.constant = 0.0f;
for (UIView *vw in commentView.subviews) {
if ([vw isKindOfClass:[UITextField class]]) {
txtComment = (UITextField *)vw;
textBottom.constant = keyboardHeight;
}
}
}
Here is one awesome solution:
https://github.com/hackiftekhar/IQKeyboardManager
It easy to integrate and effortless.
You won't have to use a UIScrollView in each of your UIViewControllers.
I have added one tableview inside xib. After that I have added headerview and footerview in that. Inside footerview there is one textview. Textview can't scroll to visible area once keyboard appears.
Let me know anyone facing the same issue.
This behavior is not handled by default. You have to implement it yourself.
The other solution is to use UITableViewController instead of UITableView, which implements this behavior by default. You could put the UITableViewController in a UIContainerView if you don't want it to take the whole frame.
See code here if you want to implement the behavior yourself How to make a UITextField move up when keyboard is present?
Hope it helps.
Here is some sample code:
#define kOFFSET_FOR_KEYBOARD 80.0
-(void)keyboardWillShow {
// Animate the current view out of the way
if (self.view.frame.origin.y >= 0)
{
[self setViewMovedUp:YES];
}
else if (self.view.frame.origin.y < 0)
{
[self setViewMovedUp:NO];
}
}
-(void)keyboardWillHide {
if (self.view.frame.origin.y >= 0)
{
[self setViewMovedUp:YES];
}
else if (self.view.frame.origin.y < 0)
{
[self setViewMovedUp:NO];
}
}
-(void)textFieldDidBeginEditing:(UITextField *)sender
{
if ([sender isEqual:mailTf])
{
//move the main view, so that the keyboard does not hide it.
if (self.view.frame.origin.y >= 0)
{
[self setViewMovedUp:YES];
}
}
}
//method to move the view up/down whenever the keyboard is shown/dismissed
-(void)setViewMovedUp:(BOOL)movedUp
{
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.3]; // if you want to slide up the view
CGRect rect = self.view.frame;
if (movedUp)
{
// 1. move the view's origin up so that the text field that will be hidden come above the keyboard
// 2. increase the size of the view so that the area behind the keyboard is covered up.
rect.origin.y -= kOFFSET_FOR_KEYBOARD;
rect.size.height += kOFFSET_FOR_KEYBOARD;
}
else
{
// revert back to the normal state.
rect.origin.y += kOFFSET_FOR_KEYBOARD;
rect.size.height -= kOFFSET_FOR_KEYBOARD;
}
self.view.frame = rect;
[UIView commitAnimations];
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
// register for keyboard notifications
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWillShow)
name:UIKeyboardWillShowNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWillHide)
name:UIKeyboardWillHideNotification
object:nil];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
// unregister for keyboard notifications while not visible.
[[NSNotificationCenter defaultCenter] removeObserver:self
name:UIKeyboardWillShowNotification
object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:UIKeyboardWillHideNotification
object:nil];
}
I have a UITextView (purpose : comment) pinned at the bottom of my screen, when the user wants to add a comment, the keyboard appears and I have the comment view shift upwards along with the comment. I also have a cancel button to hide the keyboard, but the keyboard isn't hidden
//Set up NSNotification for Keyboard
-(void) viewWillAppear:(BOOL)animated
{
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillToggle:)
name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillToggle:)
name:UIKeyboardWillHideNotification object:nil];
}
//Code to shift comment view up with keyboard
- (void) keyboardWillToggle:(NSNotification *)aNotification
{
CGRect frame = [self.navigationController.toolbar frame];
CGRect keyboard = [[aNotification.userInfo valueForKey:#"UIKeyboardFrameEndUserInfoKey"] CGRectValue];
frame.origin.y = keyboard.origin.y - frame.size.height;
[UIView animateWithDuration:[[aNotification.userInfo valueForKey:#"UIKeyboardAnimationDurationUserInfoKey"] floatValue] animations:^
{
[self.navigationController.toolbar setFrame:frame];
}];
}
//Hide keyboard
-(void)cancelComment:(UIBarButtonItem*)sender{
NSLog(#"cancelComment called");
[self.view endEditing:YES];
}
I feel like this should work? "cancelComment called" is being logged to the console but the keyboard isn't hidden
SOLUTION:
You have forgotten to put:
[yourtextfield resignfirstresponder];
in your cancelComment function.
you can try
-(void)cancelComment:(UIBarButtonItem*)sender{
NSLog(#"cancelComment called”);
[self.navigationController.view endEditing:YES];
}
I think you textView not in self.view and in the self.navigationController.view
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
[yourtextfieldname resignfirstresponder];
}
Hope this will you!
Since iOS 8, UITextFields in a form behave very strangely. If I click an another text field or press Tab on the keyboard, the entered text animates upwards then reappears quickly. It happens every time after the view did loaded, and every now and then afterwards.
It looks like this:
My code looks like this:
#pragma mark - <UITextFieldDelegate>
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
if (textField == self.passwordTextField) {
[self loginButtonClicked:nil];
} else if (textField == self.emailTextField) {
[self.passwordTextField becomeFirstResponder];
}
return YES;
}
EDIT:
It looks like this issue is caused by my keyboard listeners:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
- (void)keyboardWillHide:(NSNotification *)sender
{
self.loginBoxBottomLayoutConstraint.constant = 0;
[self.view layoutIfNeeded];
}
- (void)keyboardWillShow:(NSNotification *)sender
{
CGRect frame = [sender.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
CGRect newFrame = [self.view convertRect:frame fromView:[[UIApplication sharedApplication] delegate].window];
self.loginBoxBottomLayoutConstraint.constant = CGRectGetHeight(newFrame);
[self.view layoutIfNeeded];
}
The problem seems to be that you are executing the piece of code in
-(void)keyboardWillShow:(NSNotification *)sender
even if the keyboard is already active, which leads to some distortion.
A small work around would be to check if the keyboard is already active before adjusting the frames, as below
bool isKeyboardActive = false;
-(void)keyboardWillHide:(NSNotification *)sender
{
self.boxBottomConstraint.constant = 0;
[self.view layoutIfNeeded];
isKeyboardActive = false;
}
-(void)keyboardWillShow:(NSNotification *)sender
{
if (!isKeyboardActive) {
CGRect frame = [sender.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
CGRect newFrame = [self.view convertRect:frame fromView:[[UIApplication sharedApplication] delegate].window];
self.boxBottomConstraint.constant = CGRectGetHeight(newFrame);
[self.view layoutIfNeeded];
isKeyboardActive = true;
}
}
Try this
- (void)textFieldDidEndEditing:(UITextField *)textField
{
[textField layoutIfNeeded];
}
Which I guess should resolve your issue. Got some similar post at UITextField: When beginning input, textfield bounces up, and then bounces down
IOS8 Text in TextField Bounces on Focus
Let me know if still we have issue
Try wrapping your code in this
[UIView performWithoutAnimation:^{
// Changes we don't want animated here
}];
On my iPhone app i have a UIWebView with toolbars above an below it. the toolbar on the bottom contains a text box for the user to input some text. but when i click on the text box, the keyboard covers the bottom half of the screen.
how do i make it so that the toolbars stay above and below the webview but the the height of the webview shrinks for the keyboard to be displayed?
any guidance on this is appreciated.
thanks in advanced.
To shrink webView you need the following:
- (void) viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
}
- (void) viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil];
}
- (void)keyboardWillShow:(NSNotification *)notification
{
CGRect keyboardFrame = [notification.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
keyboardFrame = [self.view convertRect:keyboardFrame fromView:self.view.window];
NSTimeInterval keyboardAnimationDuration = [notification.userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue];
UIViewAnimationOptions keyboardAnimationCurve = [notification.userInfo[UIKeyboardAnimationCurveUserInfoKey] integerValue] << 16;
CGFloat keyboardHeight = keyboardFrame.size.height;
[UIView animateWithDuration:keyboardAnimationDuration delay:0 options:keyboardAnimationCurve
animations:^{
_webView.contentInset = UIEdgeInsetsMake(0, 0, keyboardHeight, 0)
}
completion:NULL];
}
- (void)keyboardWillHide:(NSNotification *)notification
{
NSTimeInterval keyboardAnimationDuration = [notification.userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue];
UIViewAnimationOptions keyboardAnimationCurve = [notification.userInfo[UIKeyboardAnimationCurveUserInfoKey] integerValue] << 16;
[UIView animateWithDuration:keyboardAnimationDuration delay:0 options:keyboardAnimationCurve
animations:^{
_webView.contentInset = UIEdgeInsetsZero;
}
completion:NULL];
}
In the case of additional subviews you should slightly change this code (add change of the frames for other subview)
You can implement UITextFieldDelegate in your UIViewController and set the UITextField delegate value to your controller and then implement textFieldDidBeginEditing and textFieldDidEndEditing methods in your controller to detect when editing starts/ends.
- (void)textFieldDidBeginEditing:(UITextField *)textField{
// in case you have more than one text fields in the same view
if(textField == self.YOUR_FIELD_NAME)
// change the web view height here, you can also animate it using UIView beginAnimations
CGRect frame = self.webView.frame;
frame.size.height = 200;
self.webView.frame = frame;
}
- (void)textFieldDidEndEditing:(UITextField *)textField{
// do the opposite here
}