Move UITextField above keyboard when user click on textfield - ios

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.

Related

Keyboard not hidden in ios

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!

keyboard hides in between while entering text into textfield

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 :)

manage view with keyboard and autolayout in center

I have the following view hierarchy. View->container->2 UITextfields and 1 button in containerView. The container is in the center of the screen. What I want to do is to move the container up when keyboard appears and UITextfield is behind the keyboard and move back to center when keyboard disappear. Here is the screenshot for the same.
What constraints do I need to change or do I need to add constraints in code ?
Get the frame of the container while keyboard show and update the new frame size. 'setTranslatesAutoresizingMaskIntoConstraints' is the right solution while updating frame of a view.It worked for me
#implementation ViewController
{
CGRect defaultFrame;
}
- (void)viewDidLoad {
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
}
#pragma mark Notifications
- (void)keyboardWillShow:(NSNotification *)notification {
CGSize keyboardSize = [[[notification userInfo] objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
defaultFrame = self.ContentView.frame;
[self.ContentView setTranslatesAutoresizingMaskIntoConstraints:YES];
[self.ContentView layoutIfNeeded];
CGRect contentInsets = CGRectMake(defaultFrame.origin.x, (keyboardSize.height), defaultFrame.size.width, defaultFrame.size.height);
[UIView animateWithDuration:0.5f
animations:^{
self.ContentView.frame = contentInsets;
}
completion:^(BOOL finished){
}
];
self.ContentView.frame = contentInsets;
}
- (void)keyboardWillHide:(NSNotification *)notification {
[self.ContentView setTranslatesAutoresizingMaskIntoConstraints:NO];
[UIView animateWithDuration:0.5f
animations:^{
self.ContentView.frame = defaultFrame;
}
completion:^(BOOL finished){
}
];
}
As I understand the question, you are trying to shift the entire view when the UITextField becomes the first responder (i.e. adds the keyboard to the view)? If that is the case, I would add code in the UITextField delegate method:
#define VIEW_TAG 12345
#define kKeyboardOffsetY 80.0f
- (void)textFieldDidBeginEditing:(UITextField *)textField {
// get a reference to the view you want to move when editing begins
// which can be done by setting the tag of the container view to VIEW_TAG
UIView *containerView = (UIView *)[self.view viewWithTag:VIEW_TAG];
[UIView animateWithDuration:0.3 animations:^{
containerView.frame = CGRectMake(0.0f, -kKeyboardOffsetY, containerView.frame.size.width, containerView.frame.size.height);
}];
}
- (void)textFieldDidEndEditing:(UITextField *)textField {
UIView *containerView = (UIView *)[self.view viewWithTag:VIEW_TAG];
[UIView animateWithDuration:0.3 animations:^{
containerView.frame = CGRectMake(0.0f, self.view.frame.origin.y, containerView.frame.size.width, containerView.frame.size.height);
}];
}
add UITextFieldDelegate in .h file
and try the following code it will surely help you
- (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;
}
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
}
- (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;
}];
}
Take IBOutlet of your bottom constraint or top constraint of container view by ctrl+drag from respactive constraint.
If bottom constraint then increase the constant of constraint equal to keyboard height when keyboard appears and decrease same when keyboard disappear.
If using top constraint then decrease the constant equal to keyboard height when keyboard appears and increase same when keyboard disappear.
for example,
topConstraint.constant = topConstraint.constant + keyboardHeight;
Update :
According to your constraint you should take outlet of vertically center or center x and you should do something like,
self.verticallyCenter.constant = self.horizontalyCenter.constant - 100 //here 100 is keyboardheight for example and do it in viewdidload
By this your container view will goes up to 100 pixels.
when resign keyboard you can add 100 to it's constant to get initial position back.
Hope this will help :)
Seems like you have given correct constraints all you need to do now is to make a outlet of centre y constraint and change it's constant on keyboard show/hide events, Which you can grab with keyboardDidShow/keyboardWillShow and keyboardDidHide/keyboardWillHide notifications. that said you can also add cool animation effects for these changes. Try out let me know if you need example.
Edit:
add your viewcontroller as observer for two Notifications:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWasShown:)
name:UIKeyboardDidShowNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardDidHide:)
name:UIKeyboardDidHideNotification
object:nil];
Now suppose name of your constraint is "constraintForTopSpace",then add two methods for the notifications:
- (void)keyboardWasShown:(NSNotification *)notification {
// Get the size of the keyboard.
CGSize keyboardSize = [[[notification userInfo] objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
//Given size may not account for screen rotation
int height = MIN(keyboardSize.height,keyboardSize.width);
// Here you can set your constraint's constant to lift your container up.
[UIView animateWithDuration:0.5 animations:^{
[constraintForTopSpace setConstant:constraintForTopSpace.constant - height];
[self.view layoutIfNeeded];
}];
}
- (void)keyboardDidHide:(NSNotification *)notification {
CGSize keyboardSize = [[[notification userInfo] objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
int height = MIN(keyboardSize.height,keyboardSize.width);
// Here you can set your constraint's constant to move your container down.
[UIView animateWithDuration:0.5 animations:^{
[constraintForTopSpace setConstant:constraintForTopSpace.constant + height];
[self.view layoutIfNeeded];
}];
}
And you can also use UIKeyboardWillShowNotification/UIKeyboardWillHideNotification notification they will be triggered before the keyboard appears on screen, Its up to your requirements.
Here adding animation will give smooth look and feel. ;)

iOS Keyboard show event handling

I am working on a chat app wherein I have a textview (not textfield) and when I click on it, the keyboard should show and everything should move up.
Till now, I have managed to shift the frame of the table view and textview up and show the keyboard using the below code.
- (void)keyboardWasShown:(NSNotification *)notification {
NSDictionary* info = [notification userInfo];
keyboardSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
CGPoint contentViewOrigin = self.contentView.frame.origin;
CGFloat contentViewHeight = self.contentView.frame.size.height;
CGRect visibleRect = self.view.frame;
visibleRect.size.height -= keyboardSize.height;
BOOL up = CGRectContainsPoint(visibleRect, contentViewOrigin);
if (!up){
self.tableView.frame = CGRectMake(self.tableView.frame.origin.x,self.tableView.frame.origin.y,self.tableView.frame.size.width,280.0f);
self.contentView.frame = CGRectOffset(self.contentView.frame, 0, 0 - keyboardSize.height);
if([self.tableView numberOfRowsInSection:0]!=0)
{
NSIndexPath* ip = [NSIndexPath indexPathForRow:[self.tableView numberOfRowsInSection:0]-1 inSection:0];
[self.tableView scrollToRowAtIndexPath:ip atScrollPosition:UITableViewScrollPositionBottom animated:UITableViewRowAnimationLeft];
}
}
}
- (void)keyboardWillBeHidden:(NSNotification *)notification {
self.contentView.frame = originalContentView;
self.tableView.frame = originalTable;
}
- (void)registerForKeyboardNotifications {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWasShown:)
name:UIKeyboardDidShowNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWillBeHidden:)
name:UIKeyboardWillHideNotification
object:nil];
}
- (void)deregisterFromKeyboardNotifications {
[[NSNotificationCenter defaultCenter] removeObserver:self
name:UIKeyboardDidHideNotification
object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:UIKeyboardWillHideNotification
object:nil];
}
But when I saw how whatsapp does it, mine looked like a hack. Whatsapp's keyboard moves up together with all the elements while mine works like this: First the keyboard is shown, a notification is sent to the app, notification is received, the code calculates the height of keyboard and moves up the elements according to the height.
I have searched and found the solution that I have implemented.
Can someone help??
I use this trick a lot in my apps. You want to listen to UIKeyboardWillShowNotification and UIKeyboardWillHideNotification.
The best way to handle animation in my opinion is using autolayout. When you call [self.view layoutIfNeeded]; your views will move along with the keyboard animation. No animation block needed.
I've set up a simple project for anyone to try and see how it works!
- (void)addKeyboardNotificationsObserver {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(handleKeyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(handleKeyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
}
- (void)handleKeyboardWillShow:(NSNotification *)paramNotification
{
NSDictionary* info = [paramNotification userInfo];
//when switching languages keyboard might change its height (emoji keyboard is higher than most keyboards).
//You can get both sizes of the previous keyboard and the new one from info dictionary.
// size of the keyb that is about to disappear
CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
// size of the keyb that is about to appear
CGSize kbSizeNew = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size;
//make adjustments to constraints here...
//and here where's magick happen!
[self.view layoutIfNeeded];
}
- (void)handleKeyboardWillHide:(NSNotification *)paramNotification
{
//adjust constraints
[self.view layoutIfNeeded];
}
You can use UIKeyboardWillShowNotification and UIKeyboardWillHideNotification
Try TPKeyboardAvoidingScrollView from here: https://github.com/michaeltyson/TPKeyboardAvoiding (my choice)

Shrink UIWebView when keyboard appears

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
}

Resources