在 Swift4 上通过键盘隐藏时如何滚动 UITextField?
How to Scroll UITextField when hides by Keyboard on Swift4?
我遇到了经典问题,iOS 的键盘隐藏了屏幕底部的 UITextField。因此,网络上的解决方案仅解决 <= Swift3。
那么,我如何在 Swift4 中解决这个问题?
全屏:
键盘隐藏了我的 UITextField:
我试过这篇文章:https://medium.com/@dzungnguyen.hcm/autolayout-for-scrollview-keyboard-handling-in-ios-5a47d73fd023
但是ViewController.
的self.constraintContentHeight.constant
"is not member"
你可以使用框架轻松处理那就是IQKeyboardManager
这是我个人使用的代码。它是一个 NSLayoutContraint。在故事板中,您可以 select 底部布局指南并将其 class 更改为 KeyboardNSLayoutConstraint。
import UIKit
public class KeyboardNSLayoutConstraint: NSLayoutConstraint {
private var offset : CGFloat = 0
private var keyboardVisibleHeight : CGFloat = 0
override public func awakeFromNib() {
super.awakeFromNib()
offset = constant
NotificationCenter.default.addObserver(self, selector: #selector(KeyboardLayoutConstraint.keyboardWillShowNotification(_:)), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(KeyboardLayoutConstraint.keyboardWillHideNotification(_:)), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
}
deinit {
NotificationCenter.default.removeObserver(self)
}
@objc func keyboardWillShowNotification(_ notification: Notification) {
if let userInfo = notification.userInfo {
if let frameValue = userInfo[UIKeyboardFrameEndUserInfoKey] as? NSValue {
let frame = frameValue.cgRectValue
keyboardVisibleHeight = frame.size.height
//If device is an iPhone X, it changes the layout constraint to accomodate for the bottom bar
if (UIDevice.current.modelName == "iPhone10,3") || (UIDevice.current.modelName == "iPhone10,6") {
keyboardVisibleHeight = keyboardVisibleHeight - 34
}
}
self.updateConstant()
switch (userInfo[UIKeyboardAnimationDurationUserInfoKey] as? NSNumber, userInfo[UIKeyboardAnimationCurveUserInfoKey] as? NSNumber) {
case let (.some(duration), .some(curve)):
let options = UIViewAnimationOptions(rawValue: curve.uintValue)
UIView.animate(withDuration: TimeInterval(duration.doubleValue), delay: 0, options: options, animations: { UIApplication.shared.keyWindow?.layoutIfNeeded()
return
}, completion: { finished in })
default:
break
}
}
}
@objc func keyboardWillHideNotification(_ notification: NSNotification) {
keyboardVisibleHeight = 0
self.updateConstant()
if let userInfo = notification.userInfo {
switch (userInfo[UIKeyboardAnimationDurationUserInfoKey] as? NSNumber, userInfo[UIKeyboardAnimationCurveUserInfoKey] as? NSNumber) {
case let (.some(duration), .some(curve)):
let options = UIViewAnimationOptions(rawValue: curve.uintValue)
UIView.animate(withDuration: TimeInterval(duration.doubleValue), delay: 0, options: options, animations: {
UIApplication.shared.keyWindow?.layoutIfNeeded()
return
}, completion: { finished in })
default: break
}
}
}
func updateConstant() {
self.constant = offset + keyboardVisibleHeight
}
}
您只需要将 [UIKeyboardFrameBeginUserInfoKey]
更新为 [UIKeyboardFrameEndUserInfoKey]
它会为您提供键盘的高度 + 键盘栏(如果启用)。
取作为文本字段超级视图的 topConstraint 的出口,而不是像这样在委托方法中编写一些代码
func textFieldShouldBeginEditing(textField: UITextField) -> Bool {
if textfield==txt1{
containerView(superview of textfield).topConstraint.constraint = -100 (According to you choice)
} else if textfield == txt2{
containerView(superview of textfield).topConstraint.constraint = -120 (According to you choice)
}
}
func textFieldDidEndEditing(textField: UITextField) {
containerView(superview of textfield).topConstraint.constraint = 0
}
你需要添加键盘的观察者事件会改变那更好。
extension UIView {
func bindToKeyboard() {
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillChange(_:)), name: NSNotification.Name.UIKeyboardWillChangeFrame, object: nil)
}
@objc func keyboardWillChange(_ notification: Notification) {
let duration = notification.userInfo![UIKeyboardAnimationDurationUserInfoKey] as! Double
let curve = notification.userInfo![UIKeyboardAnimationCurveUserInfoKey] as! UInt
let curveFrame = (notification.userInfo![UIKeyboardFrameBeginUserInfoKey] as! NSValue).cgRectValue
let targetFrame = (notification.userInfo![UIKeyboardFrameEndUserInfoKey] as! NSValue).cgRectValue
let deltaY = targetFrame.origin.y - curveFrame.origin.y
UIView.animateKeyframes(withDuration: duration, delay: 0.0, options: UIViewKeyframeAnimationOptions(rawValue: curve), animations: {
self.frame.origin.y += deltaY
}, completion: nil)
}
}
之后只需在 viewDidLoad() 中调用它,但请确保您必须为其设置委托。
override func viewDidLoad() {
super.viewDidLoad()
// Textfield delegation
emailTextField.delegate = self
passwordTextField.delegate = self
view.bindToKeyboard()
}
如果您遵循该媒体post,这是您的解决方案:
self.constraintContentHeight.constant 您没有得到的实际上是内容视图高度约束的 IBOutlet。
所以你需要设置连接到那个。
而已。享受!
我遇到了经典问题,iOS 的键盘隐藏了屏幕底部的 UITextField。因此,网络上的解决方案仅解决 <= Swift3。 那么,我如何在 Swift4 中解决这个问题?
全屏:
键盘隐藏了我的 UITextField:
我试过这篇文章:https://medium.com/@dzungnguyen.hcm/autolayout-for-scrollview-keyboard-handling-in-ios-5a47d73fd023 但是ViewController.
的self.constraintContentHeight.constant
"is not member"
你可以使用框架轻松处理那就是IQKeyboardManager
这是我个人使用的代码。它是一个 NSLayoutContraint。在故事板中,您可以 select 底部布局指南并将其 class 更改为 KeyboardNSLayoutConstraint。
import UIKit
public class KeyboardNSLayoutConstraint: NSLayoutConstraint {
private var offset : CGFloat = 0
private var keyboardVisibleHeight : CGFloat = 0
override public func awakeFromNib() {
super.awakeFromNib()
offset = constant
NotificationCenter.default.addObserver(self, selector: #selector(KeyboardLayoutConstraint.keyboardWillShowNotification(_:)), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(KeyboardLayoutConstraint.keyboardWillHideNotification(_:)), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
}
deinit {
NotificationCenter.default.removeObserver(self)
}
@objc func keyboardWillShowNotification(_ notification: Notification) {
if let userInfo = notification.userInfo {
if let frameValue = userInfo[UIKeyboardFrameEndUserInfoKey] as? NSValue {
let frame = frameValue.cgRectValue
keyboardVisibleHeight = frame.size.height
//If device is an iPhone X, it changes the layout constraint to accomodate for the bottom bar
if (UIDevice.current.modelName == "iPhone10,3") || (UIDevice.current.modelName == "iPhone10,6") {
keyboardVisibleHeight = keyboardVisibleHeight - 34
}
}
self.updateConstant()
switch (userInfo[UIKeyboardAnimationDurationUserInfoKey] as? NSNumber, userInfo[UIKeyboardAnimationCurveUserInfoKey] as? NSNumber) {
case let (.some(duration), .some(curve)):
let options = UIViewAnimationOptions(rawValue: curve.uintValue)
UIView.animate(withDuration: TimeInterval(duration.doubleValue), delay: 0, options: options, animations: { UIApplication.shared.keyWindow?.layoutIfNeeded()
return
}, completion: { finished in })
default:
break
}
}
}
@objc func keyboardWillHideNotification(_ notification: NSNotification) {
keyboardVisibleHeight = 0
self.updateConstant()
if let userInfo = notification.userInfo {
switch (userInfo[UIKeyboardAnimationDurationUserInfoKey] as? NSNumber, userInfo[UIKeyboardAnimationCurveUserInfoKey] as? NSNumber) {
case let (.some(duration), .some(curve)):
let options = UIViewAnimationOptions(rawValue: curve.uintValue)
UIView.animate(withDuration: TimeInterval(duration.doubleValue), delay: 0, options: options, animations: {
UIApplication.shared.keyWindow?.layoutIfNeeded()
return
}, completion: { finished in })
default: break
}
}
}
func updateConstant() {
self.constant = offset + keyboardVisibleHeight
}
}
您只需要将 [UIKeyboardFrameBeginUserInfoKey]
更新为 [UIKeyboardFrameEndUserInfoKey]
它会为您提供键盘的高度 + 键盘栏(如果启用)。
取作为文本字段超级视图的 topConstraint 的出口,而不是像这样在委托方法中编写一些代码
func textFieldShouldBeginEditing(textField: UITextField) -> Bool {
if textfield==txt1{
containerView(superview of textfield).topConstraint.constraint = -100 (According to you choice)
} else if textfield == txt2{
containerView(superview of textfield).topConstraint.constraint = -120 (According to you choice)
}
}
func textFieldDidEndEditing(textField: UITextField) {
containerView(superview of textfield).topConstraint.constraint = 0
}
你需要添加键盘的观察者事件会改变那更好。
extension UIView {
func bindToKeyboard() {
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillChange(_:)), name: NSNotification.Name.UIKeyboardWillChangeFrame, object: nil)
}
@objc func keyboardWillChange(_ notification: Notification) {
let duration = notification.userInfo![UIKeyboardAnimationDurationUserInfoKey] as! Double
let curve = notification.userInfo![UIKeyboardAnimationCurveUserInfoKey] as! UInt
let curveFrame = (notification.userInfo![UIKeyboardFrameBeginUserInfoKey] as! NSValue).cgRectValue
let targetFrame = (notification.userInfo![UIKeyboardFrameEndUserInfoKey] as! NSValue).cgRectValue
let deltaY = targetFrame.origin.y - curveFrame.origin.y
UIView.animateKeyframes(withDuration: duration, delay: 0.0, options: UIViewKeyframeAnimationOptions(rawValue: curve), animations: {
self.frame.origin.y += deltaY
}, completion: nil)
}
}
之后只需在 viewDidLoad() 中调用它,但请确保您必须为其设置委托。
override func viewDidLoad() {
super.viewDidLoad()
// Textfield delegation
emailTextField.delegate = self
passwordTextField.delegate = self
view.bindToKeyboard()
}
如果您遵循该媒体post,这是您的解决方案:
self.constraintContentHeight.constant 您没有得到的实际上是内容视图高度约束的 IBOutlet。
所以你需要设置连接到那个。 而已。享受!