1
votes

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.

6
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? - Vani
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
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 .stackoverflow.com/questions/22549911/… - Vani
Can you set the textfield as firstResponder in textFieldDidBeginEditing and check whether keyboardIsShown method is getting called and does the wonders as expected? - Vani
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

6 Answers

0
votes

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.

0
votes

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.

0
votes

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];

}
0
votes

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; 
0
votes

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.

0
votes

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;