【问题标题】:Resize the UITextView when keyboard appears出现键盘时调整 UITextView 的大小
【发布时间】:2015-01-16 20:55:05
【问题描述】:

我想在键盘出现时调整文本视图的大小。我的代码如下。我有自动布局,因此使用来自超级视图的 textView->bottom space 的约束并通过 IBOutlet distanceFromBottom 引用它。

- (void)keyboardWillShow:(NSNotification *)notification
{
  [UIView animateWithDuration:0.3 animations:^{
    NSDictionary* d = [notification userInfo];
    CGRect r = [d[UIKeyboardFrameEndUserInfoKey] CGRectValue];
    r = [textView convertRect:r fromView:Nil];
    if(IS_IPHONE_6||IS_IPHONE_6P)
      distanceFromBottom.constant = r.origin.y+78;
    else if(IS_IPHONE_5)
      distanceFromBottom.constant = r.origin.y+183;
  }];
}

上面的代码完美运行。我不明白为什么我需要为 iPhone6 添加 +78 或为 iPhone5 添加 183。这两个值是我通过反复试验得出的。如果我不添加这些,textView 会延伸到键盘下方。请帮我解开这个谜。

【问题讨论】:

    标签: ios objective-c uitextview


    【解决方案1】:

    在viewWillAppear 方法中,添加以下内容:

    - (void) viewWillAppear:(BOOL)paramAnimated{
        [super viewWillAppear:paramAnimated];
    
        [[NSNotificationCenter defaultCenter] 
            addObserver:self 
               selector:@selector(handleKeyboardDidShow:) 
                   name:UIKeyboardDidShowNotification object:nil];
    
        [[NSNotificationCenter defaultCenter]
            addObserver:self
               selector:@selector(handleKeyboardWillHide:)     
                   name:UIKeyboardWillHideNotification object:nil];    
    }
    

    然后实现通知中心的两个方法,像这样:

    - (void) handleKeyboardDidShow:(NSNotification *)paramNotification{
    
        NSValue *keyboardRectAsObject =
            [[paramNotification userInfo] 
                objectForKey:UIKeyboardFrameEndUserInfoKey];
    
        CGRect keyboardRect = CGRectZero;
        [keyboardRectAsObject getValue:&keyboardRect];
    
        yourTextView.contentInset =
            UIEdgeInsetsMake(0.0f,
                             0.0f,
                             keyboardRect.size.height,
                             0.0f);
    }
    

    另一个喜欢:

    - (void) handleKeyboardWillHide:(NSNotification *)paramNotification{
    
        yourTextView.contentInset = UIEdgeInsetsZero;
    }
    

    它适用于所有设备;)

    【讨论】:

    • 太棒了,先生。像魅力一样工作。 :)
    【解决方案2】:

    Swift / 修改版

    使用上面的内容,我做了一些调整,使用NSLayoutConstraint的改变高度constant属性时键盘显示和隐藏。如果您旋转设备,这也有效。

    1.设置 TextView 约束

    然后控制从你的高度约束拖动一个出口到类。

    2。添加以下内容

        override func viewWillAppear(animated: Bool) {
            super.viewWillAppear(animated)
    
            NSNotificationCenter.defaultCenter().addObserver(self, selector:#selector(SkillDescriptionViewController.keyboardWillShowHandle(_:)), name: UIKeyboardDidShowNotification, object: nil)
    
            NSNotificationCenter.defaultCenter().addObserver(self, selector:#selector(SkillDescriptionViewController.keyboardWillHideHandle), name: UIKeyboardWillHideNotification, object: nil)
    
        }
    
    
        func keyboardWillShowHandle(note:NSNotification) {
            guard let keyboardRect = note.userInfo![UIKeyboardFrameEndUserInfoKey] as? NSValue else { return }
            let kbFrame = keyboardRect.CGRectValue()
            tvHeight.constant = -kbFrame.height
            view.layoutIfNeeded()
        }
    
        func keyboardWillHideHandle() {
            tvHeight.constant = 0
            view.layoutIfNeeded()
        }
    

    【讨论】:

      【解决方案3】:

      基于上述答案的 Swift 5 解决方案

      Notification API 已更改(20190707)以及如何使用#selector

      当键盘弹窗覆盖 UITextView 导致用户无法看到被编辑的文本时,可以使用这里的解决方案。

      import UIKit
      
      class DCNodeLogEntryViewController: UIViewController {
          @IBOutlet weak var textViewNodeLogEntry: UITextView!
      
          override func viewWillAppear(_ animated: Bool) {
              super.viewWillAppear(animated)
      
              NotificationCenter.default.addObserver(
                  self,
                  selector: #selector(DCNodeLogEntryViewController.handleKeyboardDidShow(notification:)),
                  name: UIResponder.keyboardDidShowNotification,
                  object: nil
              )
      
              NotificationCenter.default.addObserver(
                  self,
                  selector: #selector(DCNodeLogEntryViewController.handleKeybolardWillHide),
                  name: UIResponder.keyboardWillHideNotification,
                  object: nil
              )
          }
      
          @objc func handleKeyboardDidShow(notification: NSNotification) {
              guard let keyboardRect = notification
                  .userInfo![UIResponder.keyboardFrameEndUserInfoKey]
                  as? NSValue else { return }
      
              let frameKeyboard = keyboardRect.cgRectValue
      
              textViewNodeLogEntry.contentInset = UIEdgeInsets(
                  top: 0.0,
                  left: 0.0,
                  bottom: frameKeyboard.size.height,
                  right: 0.0
              )
      
              view.layoutIfNeeded()
          }
      
          @objc func handleKeybolardWillHide() {
              textViewNodeLogEntry.contentInset = .zero
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2011-11-02
        • 1970-01-01
        • 1970-01-01
        • 2015-08-21
        • 2012-12-17
        • 1970-01-01
        • 2013-04-09
        • 1970-01-01
        相关资源
        最近更新 更多