【问题标题】:How to move view up when iOS keyboard appears?iOS键盘出现时如何向上移动视图?
【发布时间】:2015-11-29 17:12:37
【问题描述】:

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

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

我尝试添加以下内容:

-(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 年这个问题没有直接的解决方案吗?

【问题讨论】:

    标签: ios xcode keyboard textfield


    【解决方案1】:

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

    斯威夫特 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];
    
    }
    

    【讨论】:

    • 我想我不清楚。我需要将上面的“textField”更改为特定的还是通用的?如果我需要更改 viewForLogin 这是什么?我需要在属性中指定它还是将文本字段放在容器中?
    • viewForLogin 是包含您的文本字段的任何视图。它可以是 self.view 或 self.view 的任何子视图。只需设置所有三个文本字段的委托并添加上述两个委托方法。使用包含您的文本字段的相应视图更改 viewForLogin ,它将起作用。
    • 视图控制器是一个uiviewcontroller,是在storyboard中创建的。文本字段只是位于 VC 中。是否每个视图控制器都带有自己的 self.view 或者我如何知道视图的名称?
    • 我尝试使用 self.view 包括更改 viewForIpad。没有效果。除了如何将视图识别为 self.view 或其他内容之外,我是否需要将其放入滚动视图中?我还需要做什么,因为它没有效果。
    • 不需要滚动视图。我已经编辑了答案,只是 self.view 应该可以完成这项工作。检查是否调用了委托方法。
    【解决方案2】:

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

    【讨论】:

      【解决方案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];
          }
      

      【讨论】:

      • 这里的DEVICE_HEIGHT 是什么?
      猜你喜欢
      • 2018-05-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-06
      • 1970-01-01
      • 2012-02-01
      • 1970-01-01
      相关资源
      最近更新 更多