【问题标题】:Keyboard covers text fields at the bottom of my view键盘覆盖了我视图底部的文本字段
【发布时间】:2018-03-12 00:40:14
【问题描述】:

我已经搜索过了

这里:Move a view up only when the keyboard covers an input field

这里:Move textfield when keyboard appears swift

这里:How to make a UITextField move up when keyboard is present?

这里:https://developer.apple.com/library/content/documentation/StringsTextFonts/Conceptual/TextAndWebiPhoneOS/KeyboardManagement/KeyboardManagement.html

不幸的是,我能找到的所有链接以及似乎其他任何地方都没有提供我正在寻找的良好干净的解决方案。它们要么在 Obj-c 代码中过时,要么在 Xcode 9 的当前迭代中无法使用 Swift 4

如何管理覆盖视图底部文本字段的键盘?我希望屏幕视图仅在键盘覆盖文本字段视图时移动,而不使用滚动视图,能够对其进行动画处理以使其看起来很漂亮,而不是让它只是快照,最重要的是我不想使用外部库

Apple 的 CoreAnimation 库非常棒,但所有示例代码都已过时,并且在目标 c 中已被弃用(我不敢相信 Apple 没有更新他们的文档)。

如果有人可以为我指出正确的方向来更新和当前代码或我缺少的 Apple 库来专门解决这个问题,我将不胜感激。

【问题讨论】:

  • 适用于 iOS 的 AppKit?这是闻所未闻的。
  • 你是对的,更新了库

标签: ios swift view keyboard textfield


【解决方案1】:

您可以使用 IQKeyboardManagerSwift 轻松快速地解决您的问题。

在你的 pod 文件中使用下面的 pod,它支持 Swift 4。

pod 'IQKeyboardManagerSwift', '5.0.0'

这里是实现 IQKeyboardManagerSwift 的链接。

https://github.com/hackiftekhar/IQKeyboardManager

谢谢!!!

【讨论】:

  • 谢谢,但我在问题中明确表示我不想使用外部库。
  • 这是一个很棒的替代品@jaydeep Patel
【解决方案2】:

此代码将起作用,如果它的框架与键盘的框架相交,则使您的 textField 动画到键盘上方,并动画回到键盘隐藏的原始位置。

@IBOutlet weak var textField: UITextField!

  var offsetY:CGFloat = 0

  override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    NotificationCenter.default.addObserver(self, selector: #selector(ViewController.keyboardFrameChangeNotification(notification:)), name: NSNotification.Name.UIKeyboardWillChangeFrame, object: nil)
  }

  func keyboardFrameChangeNotification(notification: Notification) {
    if let userInfo = notification.userInfo {
      let endFrame = userInfo[UIKeyboardFrameEndUserInfoKey] as? CGRect
      let animationDuration = userInfo[UIKeyboardAnimationDurationUserInfoKey] as? Double ?? 0
      let animationCurveRawValue = (userInfo[UIKeyboardAnimationCurveUserInfoKey] as? Int) ?? Int(UIViewAnimationOptions.curveEaseInOut.rawValue)
      let animationCurve = UIViewAnimationOptions(rawValue: UInt(animationCurveRawValue))
      if let _ = endFrame, endFrame!.intersects(self.textField.frame) {
        self.offsetY = self.textField.frame.maxY - endFrame!.minY
        UIView.animate(withDuration: animationDuration, delay: TimeInterval(0), options: animationCurve, animations: {
          self.textField.frame.origin.y = self.textField.frame.origin.y - self.offsetY
        }, completion: nil)
      } else {
        if self.offsetY != 0 {
          UIView.animate(withDuration: animationDuration, delay: TimeInterval(0), options: animationCurve, animations: {
            self.textField.frame.origin.y = self.textField.frame.origin.y + self.offsetY
            self.offsetY = 0
          }, completion: nil)
        }
      }
    }
  }

【讨论】:

  • "在展开可选值时意外发现 nil。"如果使用通知,该函数如何知道我在说哪个文本字段?我有多个,您没有告诉示例中的函数如何解开 textField。
  • TextField 在我的示例中不是可选的,因此无需打开它。我想你错过了它是一个 IBOutlet。对于多个文本字段,您可以找出第一响应者,计算在代码中完成的 offsetY 并相应地为您的整个视图设置动画。
  • 别忘了删除“viewWillDisappear”中的观察者
【解决方案3】:

这段代码对我有用。

如果有多个文本字段

我只为底部的文本字段实现了(不使用通知观察者)。

如果您使用的是 scrollView,此代码可能会有所帮助 (scrollViewDidScroll 是可选的)

func scrollViewDidScroll(_ scrollView: UIScrollView) {
    scrollView.contentSize = CGSize(width: self.scrollView.frame.size.width, height: (scrollView.frame.size.height + 300))// To be more specific, I have used multiple textfields so wanted to scroll to the end.So have given the constant 300.
}

func textFieldDidBeginEditing(_ textField:UITextField) {
    self.scrollView.setContentOffset(textField.frame.origin, animated: true)
}

如果你想根据视图设置文本字段的位置, 试试这个:

func textFieldDidBeginEditing(_ textField:UITextField){
    textField.frame.origin.y = textField.frame.origin.y - 150 //(If have not used contentsizing the scroll view then exclude this line)default origin takes the texfield to the top of the view.So to set lower textfields to proper position have used the constant 150.
    self.scrollView.setContentOffset(textField.frame.origin, animated: true)
}

专门为底部的文本字段做。在 textFieldDidBeginEditing

中检查他们的标签值 textfield.tag
func textFieldDidBeginEditing(_ textField:UITextField){
    if textField.tag = 4 { //tag value of the textfield which are at the bottom
        self.scrollView.setContentOffset(textField.frame.origin, animated: true)
    }
}

如果您在 tableView 中实现了文本字段,请使用下面解释的通知观察器。

如果 tableView 中有多个文本字段,最好使用 Notification Observer

override func viewDidAppear(_ animated: Bool) {
    NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(notification:)), name: NSNotification.Name.UIKeyboardDidShow, object: nil)
    NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide(notification:)), name: NSNotification.Name.UIKeyboardDidHide, object: nil)
}

@objc func keyboardWillShow(notification: NSNotification) {
    if let keyboardHeight = (notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue.height {
        self.tableView.contentInset = UIEdgeInsetsMake(0, 0, keyboardHeight, 0)
    }
}

@objc func keyboardWillHide(notification: NSNotification) {
    UIView.animate(withDuration: 0.2, animations: {
        // For some reason adding inset in keyboardWillShow is animated by itself but removing is not, that's why we have to use animateWithDuration here
        self.tableView.contentInset = UIEdgeInsetsMake(0, 0, 0, 0)
    })
}

deinit {
    print("denit")
    NotificationCenter.default.removeObserver(self)
}

【讨论】:

    【解决方案4】:

    非常适合我: http://www.seemuapps.com/move-uitextfield-when-keyboard-is-presented

    如果代理设置正确,

     func textFieldDidBeginEditing(_ textField: UITextField) {
            moveTextField(textField, moveDistance: -250, up: true)
        }
    
        // Finish Editing The Text Field
        func textFieldDidEndEditing(_ textField: UITextField) {
            moveTextField(textField, moveDistance: -250, up: false)
        }
    
        // Hide the keyboard when the return key pressed
        func textFieldShouldReturn(_ textField: UITextField) -> Bool {
            textField.resignFirstResponder()
            return true
        }
    
        // Move the text field in a pretty animation!
        func moveTextField(_ textField: UITextField, moveDistance: Int, up: Bool) {
            let moveDuration = 0.3
            let movement: CGFloat = CGFloat(up ? moveDistance : -moveDistance)
    
            UIView.beginAnimations("animateTextField", context: nil)
            UIView.setAnimationBeginsFromCurrentState(true)
            UIView.setAnimationDuration(moveDuration)
            self.view.frame = self.view.frame.offsetBy(dx: 0, dy: movement)
            UIView.commitAnimations()
        }
    

    【讨论】:

      【解决方案5】:

      为 Uiview 添加扩展:

      import UIKit
      

      //将视图绑定到键盘更改 扩展 UIView {

      func bindToKeyboard(){
          NotificationCenter.default.addObserver(self, selector: #selector(UIView.keyboardWillChange(_:)), name: NSNotification.Name.UIKeyboardWillChangeFrame, object: nil)
      }
      
      
      
      @objc func keyboardWillChange(_ notification: NSNotification) {
          let duration = notification.userInfo![UIKeyboardAnimationDurationUserInfoKey] as! Double
          let curve = notification.userInfo![UIKeyboardAnimationCurveUserInfoKey] as! UInt
          let curFrame = (notification.userInfo![UIKeyboardFrameBeginUserInfoKey] as! NSValue).cgRectValue
          let targetFrame = (notification.userInfo![UIKeyboardFrameEndUserInfoKey] as! NSValue).cgRectValue
          let deltaY = targetFrame.origin.y - curFrame.origin.y
      
          UIView.animateKeyframes(withDuration: duration, delay: 0.0, options: UIViewKeyframeAnimationOptions(rawValue: curve), animations: {
              self.frame.origin.y += deltaY
      
          },completion: {(true) in
              self.layoutIfNeeded()
          })
      }
      

      }

      【讨论】:

      • 最失败的答案。需要一些调整,但确实是最好的解决方案。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-08-07
      • 2020-10-13
      • 2021-07-06
      • 2020-09-25
      相关资源
      最近更新 更多