IOS/Xcode: How to Move View Up when Keyboard appears

大憨熊 提交于 2019-12-09 07:09:52

问题


There are many answers on this on SO but most are from years ago and none seem quite satisfactory.

For a login screen with just three textfields and submit button, I want the view to move up when the keyboard appears just enough so that while the field is not hidden, it also does not move up out of view. The amount of movement needed is such that the submit button is a fixed distance above the keyboard. While it is possible by moving the fields high up on the page to leave room for the keyboard, the submit button is still hidden

I tried just adding the following:

-(void) viewWillAppear:(BOOL)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 {
    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil];
    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil];
}

This moves the view up a fixed amount but so much so that the fields are not visible for editing, i.e. they are too high up.

Another SO answer suggested:

-(void)textFieldDidBeginEditing:(UITextField *)textField
{
    [self animateTextField:textField up:YES];
}

- (void)textFieldDidEndEditing:(UITextField *)textField
{
    [self animateTextField:textField up:NO];
}

-(void)animateTextField:(UITextField*)textField up:(BOOL)up
{
    const int movementDistance = -200; // tweak as needed
    const float movementDuration = 0.3f; // tweak as needed

    int movement = (up ? movementDistance : -movementDistance);

    [UIView beginAnimations: @"animateTextField" context: nil];
    [UIView setAnimationBeginsFromCurrentState: YES];
    [UIView setAnimationDuration: movementDuration];
    self.view.frame = CGRectOffset(self.view.frame, 0, movement);
    [UIView commitAnimations];
}

I can't figure out how to implement this. If you just leave it as is nothing happens. I guess you are supposed to rename textfield with the name of your textfield but in that case, would you do it for each of the textfields? I cannot get it to have any effect.

Another suggestion is to use a category such as TPKeyboardAvoiding however this requires a scrollview that I do not need in this case.

Is there no straightforward solution in 2015 for this issue?

Thanks for any suggestions/guidance.


回答1:


The following animation will move your view (viewForLogin in this case) 200 pixels above when the user starts typing. The view will animate back to original position when the textfield ends editing. Do not forget to set the delegates for the textfields.

Swift 3

func textFieldDidBeginEditing(_ textField: UITextField) {
    UIView.animate(withDuration: 0.3, animations: {
        self.view.frame = CGRect(x:self.view.frame.origin.x, y:self.view.frame.origin.y - 200, width:self.view.frame.size.width, height:self.view.frame.size.height);

    })
}

func textFieldDidEndEditing(_ textField: UITextField) {
    UIView.animate(withDuration: 0.3, animations: {
        self.viewSupport.frame = CGRect(x:self.viewSupport.frame.origin.x, y:self.viewSupport.frame.origin.y + 200, width:self.viewSupport.frame.size.width, height:self.viewSupport.frame.size.height);

    })
}

Objective-C

-(void)textFieldDidBeginEditing:(UITextField *)textField
{
    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationDuration:.3];
    [UIView setAnimationBeginsFromCurrentState:TRUE];
    self.view.frame = CGRectMake(self.view.frame.origin.x, self.view.frame.origin.y -200., self.view.frame.size.width, self.view.frame.size.height);

    [UIView commitAnimations];


}


-(void)textFieldDidEndEditing:(UITextField *)textField
{
    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationDuration:.3];
    [UIView setAnimationBeginsFromCurrentState:TRUE];
    self.view.frame = CGRectMake(self.view.frame.origin.x, self.view.frame.origin.y +200., self.view.frame.size.width, self.view.frame.size.height);

    [UIView commitAnimations];

}



回答2:


SWIFT lovers Here you go. I have used this code with UIView, though. You should be able to make those adjustments for scrollview.

    func addKeyboardNotifications() {
        NotificationCenter.default.addObserver(self,
                                               selector: #selector(keyboardWillShow(notification:)),
                                               name: NSNotification.Name.UIKeyboardWillShow, object: nil)
        NotificationCenter.default.addObserver(self,
                                               selector: #selector(keyboardWillHide(notification:)),
                                               name: NSNotification.Name.UIKeyboardWillHide, object: nil)
    }

    func keyboardWillShow(notification: NSNotification) {

        if let keyboardSize = (notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue {
            let duration = notification.userInfo![UIKeyboardAnimationDurationUserInfoKey] as! Double
// if using constraints            
// bottomViewBottomSpaceConstraint.constant = keyboardSize.height
self.view.frame.origin.y -= keyboardSize.height
            UIView.animate(withDuration: duration) {
                self.view.layoutIfNeeded()
            }
        }
    }
    func keyboardWillHide(notification: NSNotification) {

        let duration = notification.userInfo![UIKeyboardAnimationDurationUserInfoKey] as! Double
//if using constraint
//        bottomViewBottomSpaceConstraint.constant = 0
self.view.frame.origin.y = 0
        UIView.animate(withDuration: duration) {
            self.view.layoutIfNeeded()
        }
    }

Don't forget to remove notifications at right place.

func removeKeyboardNotifications() {
    NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillShow, object: nil)
    NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillHide, object: nil)
}



回答3:


#define DEVICE_HEIGHT [[UIScreen mainScreen] bounds].size.height       
 -(void)viewDidLoad {

            [super viewDidLoad];

         // register for keyboard notifications

            [[NSNotificationCenter defaultCenter] addObserver:self
                                                     selector:@selector(keyboardWillShow:)
                                                         name:UIKeyboardWillShowNotification
                                                       object:self.view.window];

            [[NSNotificationCenter defaultCenter] addObserver:self
                                                     selector:@selector(keyboardWillHide:)
                                                         name:UIKeyboardWillHideNotification
                                                       object:self.view.window];

        }

        -(void)viewWillDisappear:(BOOL)animated

        {

        [super viewWillDisappear:animated];
            // unregister for keyboard notifications while not visible.

            [[NSNotificationCenter defaultCenter] removeObserver:self
                                                            name:UIKeyboardWillShowNotification
                                                          object:self.view.window];

            [[NSNotificationCenter defaultCenter] removeObserver:self
                                                            name:UIKeyboardWillHideNotification
                                                          object:self.view.window];
        }

    -(void)keyboardWillShow:(NSNotification *)noti

     {

        NSDictionary* userInfo = [noti userInfo];
        CGRect keyboardRect = [[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey]   
        CGRectValue];
        keyboardRect = [self.view convertRect:keyboardRect fromView:nil];

        CGRect viewFrame = self.view.frame;
        viewFrame.size.height = DEVICE_HEIGHT - CGRectGetHeight(keyboardRect);

        [UIView beginAnimations:nil context:NULL];
        [UIView setAnimationDuration:0.1];
        [UIView setAnimationBeginsFromCurrentState:YES];
        self.view.frame = viewFrame;

        CGPoint bottomOffset = CGPointMake(0, self.scrollView.contentSize.height  
                               - self.view.bounds.size.height);
        [self.scrollView setContentOffset:bottomOffset animated:NO];

        [UIView commitAnimations];

    }

    -(void)keyboardWillHide:(NSNotification *)noti

     {

        NSDictionary* userInfo = [noti userInfo];
        CGRect keyboardRect = [[userInfo 
                       objectForKey:UIKeyboardFrameEndUserInfoKey]CGRectValue];

        keyboardRect = [self.view convertRect:keyboardRect fromView:nil];

        CGRect viewFrame = self.view.frame;
        viewFrame.size.height = DEVICE_HEIGHT;

        [UIView beginAnimations:nil context:NULL];
        [UIView setAnimationDuration:0.1];
        [UIView setAnimationBeginsFromCurrentState:YES];
        self.view.frame = viewFrame;
        [UIView commitAnimations];
    }


来源:https://stackoverflow.com/questions/32382892/ios-xcode-how-to-move-view-up-when-keyboard-appears

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!