iOS 键盘出现时如何向上移动视图?

How to move view up when iOS keyboard appears?

对于只有三个文本字段和提交按钮的登录屏幕,我希望当键盘出现时视图向上移动,这样当字段没有隐藏时,它也不会向上移出视图。

所需的移动量使得提交按钮在键盘上方有固定距离。虽然可以通过将字段移到页面的高处为键盘留出空间,但提交按钮仍然隐藏

我尝试只添加以下内容:

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

这会将视图向上移动一个固定的量,但移动的幅度太大以至于无法看到无法编辑的字段,即它们太高了。

建议的另一个 SO 答案:

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

我不知道如何实现它。如果你只是保持原样,什么也不会发生。我猜你应该用你的文本字段的名称重命名文本字段,但在那种情况下,你会为​​每个文本字段都这样做吗?我无法让它发挥任何作用。

另一个建议是使用诸如 TPKeyboardAvoiding 之类的类别,但是这需要一个滚动视图,在这种情况下我不需要。

这个问题在2015年没有直接的解决方案吗?

当用户开始输入时,以下动画会将您的视图(在本例中为 viewForLogin)移动到上方 200 像素。当文本字段结束编辑时,视图将动画回到原始位置。不要忘记为文本字段设置委托。

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

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

SWIFT情侣 干得好。不过,我已将此代码与 UIView 一起使用。您应该能够对滚动视图进行这些调整。

    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()
        }
    }

不要忘记在正确的位置删除通知。

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