1

I have a view with additional UIView that in fact is a container for 2 UITextFields

When any of these text fiels become first responder i need to move them up because when keyboard is opened text fields are not visible. I am handling UIKeyboardDidShowNotification and UIKeyboardDidHideNotification and change frame of container view with text fields like this:

#pragma mark - Keyboard notifications handling

- (void) keyboardIsShown:(NSNotification *)notification {
    // Moving up text field while keyboard is opened

    CGRect containerFrame = self.viewContainerCredentials.frame;
    containerFrame.origin.y -= kCredentialsViewOffset;

    [UIView beginAnimations:@"moveUp" context:nil];
    [UIView setAnimationDuration:0.5f];
    self.viewContainerCredentials.frame = containerFrame;
    [UIView commitAnimations];
}

- (void) keyboardIsHidden:(NSNotification *)notification {
    // Moving down text field while keyboard is closed

    CGRect containerFrame = self.viewContainerCredentials.frame;
    containerFrame.origin.y += kCredentialsViewOffset;

    [UIView beginAnimations:@"moveDown" context:nil];
    [UIView setAnimationDuration:0.5f];
    self.viewContainerCredentials.frame = containerFrame;
    [UIView commitAnimations];
}

When I activate one of text fields - everything is working perfect and when I close the keyboard - view container moves back down correctly as well.

But when I tap first field and view container is moved up and then I tap and activate second text field without closing the keyboard - my view container restores its initial frame and goes back under the keyboard.

Can anybody help with this? Why does it happen?

Thank you in advance.

UPD: Problem was deeper: there wrongly configured auto layouts for view container that were pushed back after each resigning of first responder.

Anton Holub
  • 468
  • 1
  • 5
  • 9
  • i guess since the view container's y origin is already changed in the line containerFrame.origin.y -= kCredentialsViewOffset; in the keyboardIsShown method,without hiding the keyboard clicking on second textfield are you sure it calls the keyboardIsShown method? – Kalaivani Jul 13 '15 at 11:15
  • Vani, when tapping on second text field keyboard notifications are not thrown - keyboard is already opened after tapping on first text field. Also, As you can see I am animating view container to move up to be over the keyboard and it is restored back to down after tapping secomd – Anton Holub Jul 13 '15 at 11:24
  • http://macoscope.com/blog/working-with-keyboard-on-ios/ this link will help you and please go through this link if your textfield's input accessory view is not set .http://stackoverflow.com/questions/22549911/why-is-uikeyboardwillshownotification-called-every-time-new-textfield-is-selecte – Kalaivani Jul 13 '15 at 11:26
  • Can you set the textfield as firstResponder in textFieldDidBeginEditing and check whether keyboardIsShown method is getting called and does the wonders as expected? – Kalaivani Jul 13 '15 at 11:31
  • Keyboard notification work correctly. I've added observer for changing container view frame and I can see that after tapping the second text field the frame of container view is change by some system call... – Anton Holub Jul 13 '15 at 11:35

6 Answers6

0

Instead of doing this manually. use TPKeyboardAvoidingScrollView. Its easy to use.

First take UIScrollView and put ur all views inside it.

For use with UITableViewController classes, drop TPKeyboardAvoidingTableView.m and TPKeyboardAvoidingTableView.h into your project, and make your UITableView a TPKeyboardAvoidingTableView in the xib. If you're not using a xib with your controller, I know of no easy way to make its UITableView a custom class: The path of least resistance is to create a xib for it.

For non-UITableViewControllers, drop the TPKeyboardAvoidingScrollView.m and TPKeyboardAvoidingScrollView.h source files into your project, pop a UIScrollView into your view controller's xib, set the scroll view's class to TPKeyboardAvoidingScrollView, and put all your controls within that scroll view. You can also create it programmatically, without using a xib - just use the TPKeyboardAvoidingScrollView as your top-level view.

iAnurag
  • 9,286
  • 3
  • 31
  • 48
  • Add a scroll view or any other component based on it will work, but I need to do it manually with animating the view container moving. – Anton Holub Jul 13 '15 at 11:25
0

Would recommend you to use TPKeyboardAvoiding as it handles all such issue related to keyboard with textfield. You can install it from cocoapods in your project and use it throughout the app seamlessly.

aman.sood
  • 872
  • 7
  • 19
0

We can do this kind of animation using UITextField Delegate methods.

This is the way we followed to move the view(y=218) with animation when UITextfield becomeFirstResponder.

Here i am placing two textfields in one view. When any of the textfield becomeFirstResponder i am moving the view to up i.e.,y=100. And moving the view to its initial position when user touched any where in the screen or when tapped return key in keyboard.

- (void)textFieldDidBeginEditing:(UITextField *)textField
{
    [self moveViewUp];
}

- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
   [textField resignFirstResponder];
   [self moveViewDown];

   return YES;
}

-(void)moveViewUp
{
   __block CGRect rect=_vwForTextFields.frame;
   [UIView animateWithDuration:0.3 delay:0.0 options:UIViewAnimationOptionTransitionNone animations:^{

    if (rect.origin.y==218)
    {
        rect.origin.y=100;
        _vwForTextFields.frame=rect;

    }

   } completion:^(BOOL finished) {
    NSLog(@"View moved up");
   }];

}

-(void)moveViewDown
{
   __block CGRect rect=_vwForTextFields.frame;
   [UIView animateWithDuration:0.3 delay:0.0 options:UIViewAnimationOptionTransitionNone animations:^{

    if (rect.origin.y==100)
    {
        rect.origin.y=218;
        _vwForTextFields.frame=rect;

    }

   } completion:^(BOOL finished) {
    NSLog(@"View moved down");
   }];
}

//To dismiss keyboard when touched anywhere on screen
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
   [self.view endEditing:YES];
   [self moveViewDown];

}
user4261201
  • 2,324
  • 19
  • 26
  • According to the code my understanding that after tapping on Return button on a keyboard the keyboard will be dismissed? – Anton Holub Jul 13 '15 at 11:39
  • Actually looks like not the best solution. When you resign first responder it means that the keyboard will be dismissed and after tapping on next input - it will become first responder and because the keyboard was previously hidden it will be shown again – Anton Holub Jul 13 '15 at 12:29
  • 1
    You can do as per your requirement when to resign the keyboard. Here for myself i am resigning on tapping of return key. We can handle the return key as per requirement. Suppose after editing first textfield, we can point second textfield automatically when return key tapped instead of resigning for the first textfield. – user4261201 Jul 13 '15 at 12:40
0

Hi Keyboard notification method(keyboardIsShown) will work when the keyboard is not shown that is first when you click on the textfield keyboard pop up. When you switch to next textfield the keyboard is already present so the the method is not called the second time. If you wish to move the textfield with the current implementation what you can do is set the delegate for the textfield and implement this delegate methods in your viewcontroller

//This will be called every time you click on the textfield. You can implement the method for moving the view up here   
    - (void)textFieldDidBeginEditing:(UITextField *)textField;


//Called when you have moved out of the textfield. You can implement when the keyboard is hiding.

    - (void)textFieldDidEndEditing:(UITextField *)textField; 
Ashwin P
  • 501
  • 1
  • 3
  • 19
  • That is correct and that is the point - when keyboardIsShwon is called for the first time the view container is popped up. When I tap second text field with opened keyboard - keyboard notifications are not called and it is correct - I do not need to move the container after second tap. But the problem is that in this case keyboard notifications are not called but the view is moved down to initial position – Anton Holub Jul 13 '15 at 11:46
0

Problem was deeper - there were wrongly configure autolayouts for view container that were pushed back by system after making first responder any other control on main view.

Anton Holub
  • 468
  • 1
  • 5
  • 9
0

I had the same problem and this post just saved me. After i read the update about problems with autolayout i realized that my problem was exactly this, so i added this line to my code to the first line in the keyboardIsShown method, in order to disable the autolayout and then i activate it again in keyboardIsHidden.

In keyboardIsShown: view.TranslatesAutoresizingMaskIntoConstraints = true;

In keyboardIsHidden: view.TranslatesAutoresizingMaskIntoConstraints = false;

Community
  • 1
  • 1