简体   繁体   中英

IOS: Move TextField Up When Keyboard Appears

I am using the following method to move the view upwards when the keyboard appears so the keyboard does not block a textfield. Basically, I embed the textfields in a scrollview and scroll upwards when the keyboard appears.

// Called when the UIKeyboardDidShowNotification is sent.
- (void)keyboardWasShown:(NSNotification*)aNotification
{
    NSDictionary* info = [aNotification userInfo];
    CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;

    UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, kbSize.height, 0.0);
    _scrollView.contentInset = contentInsets;
    _scrollView.scrollIndicatorInsets = contentInsets;

    // If active text field is hidden by keyboard, scroll it so it's visible
    // Your app might not need or want this behavior.
    CGRect aRect = self.view.frame;
    aRect.size.height -= kbSize.height;
    if (!CGRectContainsPoint(aRect, _activeField.frame.origin) ) {
        [_scrollView scrollRectToVisible:_activeField.frame animated:YES];
    }
}

However, when the textfield is already at the top of the view and there is no need for it to jump up, the above code causes it to jump up out of view.

Somewhere I recall reading that there is a line you can add to prevent that but I can't remember it. Basically, it would test if the textfield is already high enough up that the keyboard won't cover it and therefore, the view does not need to be moved.

The if statement in above code does not appear to be screening out cases where the textfield is not hidden.

Can anyone suggest a way to do this?

Thank you.

If you are using autolayout, you should use constraints to manipulate the view instead of frames. You could try manipulating the bottom spacing of your textField or view to its superview as per your need and putting the layoutIfNeeded call inside an animation block. Also you can check if the value of your bottom constraint is already a particular value or pass a bool on UIKeyboardWillHideNotification and UIKeyboardWillShowNotification , if it is, then the value of the constraint should not change. Something like:

-(void)showViewAnimatedly:(BOOL)show{

    if(show){
        [bottomConstraint setConstant:0];
    }else{
        [bottomConstraint setConstant:-160];
    }

    [UIView animateWithDuration:0.3f animations:^{

        [self.view layoutIfNeeded];

    }];
}

I would also recommend using UIKeyboardWillShowNotification instead of UIKeyboardDidShowNotification as the transition seems more in tune with the keyboard appearing. UIKeyboardDidShowNotification will start the transition AFTER keyboard appears.

Check out 'IQKeyboardManager'. It is an excellent control for your requirements. And it requires only one line of code from you. It works for both UITextFields and UITextViews. It also has the option for previous and next buttons. You can install it in your project as a cocoapod

https://www.cocoacontrols.com/controls/iqkeyboardmanager

its simple when keyboard appears change the y axis co-ordinate of your textview or textfield with animation if requires. The code you can refer is below---->

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM