【问题标题】:UIScrollView scroll up on KeyboardUIScrollView 在键盘上向上滚动
【发布时间】:2017-08-11 11:10:08
【问题描述】:

问题陈述:我有 UIView 的 Nib 文件包含 UIScrollview,在滚动视图中我有几个 TextFields 和底部的 TextView。我想要的是在 textfield 或 Textview 开始编辑时向上滚动。

我尝试了什么:

在客户方法

NotificationCenter.default.addObserver(self, selector: #selector(keyboardWasShown(notification:)), name: NSNotification.Name.UIKeyboardWillShow, object: nil)

我正在调用这个方法父视图。

通知处理:

func keyboardWasShown(notification: NSNotification)
{
    var userInfo = notification.userInfo!
    var keyboardFrame:CGRect = (userInfo[UIKeyboardFrameBeginUserInfoKey] as! NSValue).cgRectValue
    keyboardFrame = self.convert(keyboardFrame, from: nil)

    var contentInset:UIEdgeInsets = self.mainScroll.contentInset
    contentInset.bottom = keyboardFrame.size.height
    self.mainScroll.contentInset = contentInset
}

这对 UITextFields 非常有效,但不适用于 UITextView。知道错误在哪里。

PS:我也设置了 UITextField 和 UITextView 的 Delegates。

任何帮助将不胜感激。

【问题讨论】:

  • 你可以使用 contentoffset 来滚动滚动视图。
  • 使用github.com/hackiftekhar/IQKeyboardManager,它会自动检测 textField 或 textView 并相应地管理所有键盘处理。
  • @ZahidShabbir : 在 textview 的情况下,scrollview 没有向上滚动或滚动一点?
  • @zahidshabbir : 你试过使用 contentOffset 吗?
  • @zahidshabbir 请看下面的答案。

标签: ios ipad uiscrollview keyboard uitextview


【解决方案1】:

用下面的函数替换keyboardWasShown函数:

 func keyboardWasShown(notification: NSNotification)
{
    var userInfo = notification.userInfo!
    var keyboardFrame:CGRect = (userInfo[UIKeyboardFrameBeginUserInfoKey] as! NSValue).cgRectValue
    keyboardFrame = self.convert(keyboardFrame, from: nil)
    self.mainScroll.contentOffset = CGPoint(x: 0, y: keyboardFrame.size.height - Any number that fits your need.)
}

在 keyBoardWillHide 中:

self.mainScroll.contentOffset = CGPoint(x: 0, y: 0)

希望它会有所帮助。 快乐编码!

【讨论】:

    【解决方案2】:

    演示链接:https://github.com/harshilkotecha/UIScrollViewWhenKeyboardAppearInSwift3

    当你有多个文本视图时,它是如此困难,所以最好的解决方案 ->

    第 1 步:添加 UITextFieldDelegate

    class ScrollViewController: UIViewController,UITextFieldDelegate {
    

    第 2 步:创建新的 IBOutlet 但不连接任何文本字段

    //  get current text box when user Begin editing
        @IBOutlet weak var activeTextField: UITextField?
    

    第3步:当用户关注文本字段对象时编写这两个方法传递引用并存储在activeTextField中

    // get current text field
        func textFieldDidBeginEditing(_ textField: UITextField)
        {
            activeTextField=textField;
        }
        func textFieldDidEndEditing(_ textField: UITextField)
        {
            activeTextField=nil;
        }
    

    第5步:在viewdidload中设置通知setNotificationKeyboard

    override func viewWillAppear(_ animated: Bool) {
            // call method for keyboard notification
            self.setNotificationKeyboard()
        }
    
        // Notification when keyboard show
        func setNotificationKeyboard ()  {
            NotificationCenter.default.addObserver(self, selector: #selector(keyboardWasShown(notification:)), name: .UIKeyboardWillShow, object: nil)
            NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillBeHidden(notification:)), name: .UIKeyboardWillHide, object: nil)
        }
    

    第6步:隐藏和显示键盘的两种方法

    func keyboardWasShown(notification: NSNotification)
        {
            var info = notification.userInfo!
            let keyboardSize = (info[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue.size
            let contentInsets : UIEdgeInsets = UIEdgeInsetsMake(0.0, 0.0, keyboardSize!.height+10, 0.0)
            self.scrollView.contentInset = contentInsets
            self.scrollView.scrollIndicatorInsets = contentInsets
            var aRect : CGRect = self.view.frame
            aRect.size.height -= keyboardSize!.height
            if let activeField = self.activeTextField
            {
                if (!aRect.contains(activeField.frame.origin))
                {
                    self.scrollView.scrollRectToVisible(activeField.frame, animated: true)
                }
            }
        }
        // when keyboard hide reduce height of scroll view
        func keyboardWillBeHidden(notification: NSNotification){
            let contentInsets : UIEdgeInsets = UIEdgeInsetsMake(0.0, 0.0,0.0, 0.0)
            self.scrollView.contentInset = contentInsets
            self.scrollView.scrollIndicatorInsets = contentInsets
            self.view.endEditing(true)
        }
    

    【讨论】:

      【解决方案3】:

      斯威夫特 5

      NotificationCenter.default.addObserver(self, selector: #selector(keyboardNotification), name: UIResponder.keyboardDidChangeFrameNotification, object: nil)
      
      
      @objc func keyboardNotification(_ notification: Notification) {
              if let userInfo = (notification as NSNotification).userInfo {
                  let endFrame = (userInfo[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue
                  let duration:TimeInterval = (userInfo[UIResponder.keyboardAnimationDurationUserInfoKey] as? NSNumber)?.doubleValue ?? 0
                  let animationCurveRawNSN = userInfo[UIResponder.keyboardAnimationCurveUserInfoKey] as? NSNumber
                  let animationCurveRaw = animationCurveRawNSN?.uintValue ?? UIView.AnimationOptions().rawValue
                  let animationCurve:UIView.AnimationOptions = UIView.AnimationOptions(rawValue: animationCurveRaw)
                  if (endFrame?.origin.y)! >= UIScreen.main.bounds.size.height {
                      scrollViewBottomConstraint?.constant = 0
                  } else {
                      if tabBarController?.tabBar.frame == nil {
                          return
                      }
                      scrollViewBottomConstraint?.constant = endFrame!.size.height - (tabBarController?.tabBar.frame.height)!
                      let bottomOffset = CGPoint(x: 0, y: 0)
                      scrollView.setContentOffset(bottomOffset, animated: true)
                  }
                  UIView.animate(withDuration: duration, delay: 0, options: animationCurve, animations: { self.view.layoutIfNeeded() }, completion: nil)
              }
          }
      

      用法:

      1.connect the scrollView outlet to your controller and set its name to 'scrollView'
      2.connect the scrollView bottom constraint to your controller & set its name to 'scrollViewBottomConstraint'
      3.put the notification observer to your ViewDidLoad function.
      

      【讨论】:

        猜你喜欢
        • 2017-08-24
        • 1970-01-01
        • 2011-08-30
        • 2015-02-15
        • 1970-01-01
        • 2016-12-17
        • 1970-01-01
        • 2022-10-09
        • 2014-04-10
        相关资源
        最近更新 更多