键盘覆盖 UITextView
Keyboard covers UITextView
我有一个扩展程序可以向上滚动 scrollView,因此它不会覆盖 UITextField,但是对于 UITextView 它不会向上滚动。扩展名如下所示:
extension SummaryViewController {
///Register for keyboard willHide willShow notifiication
func registerKeyboardNotifications() {
NotificationCenter.default.addObserver(self,
selector: #selector(SummaryViewController.keyboardNotification(notification:)),
name: UIResponder.keyboardWillChangeFrameNotification, object: nil)
}
@objc func keyboardNotification(notification: NSNotification) {
if let userInfo = notification.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.curveEaseInOut.rawValue
let animationCurve: UIView.AnimationOptions = UIView.AnimationOptions(rawValue: animationCurveRaw)
if (endFrame?.origin.y)! >= UIScreen.main.bounds.size.height {
//close keyboard
scrollView.contentInset = .zero
} else {
//open keyboard
let height: CGFloat = (notification.userInfo![UIResponder.keyboardFrameEndUserInfoKey] as? CGRect)!.size.height
scrollView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: height, right: 0)
}
UIView.animate(withDuration: duration,
delay: TimeInterval(0),
options: animationCurve,
animations: { self.view.layoutIfNeeded() },
completion: nil)
}
}
}
我在 viewDidLoad 中调用 registerKeyboardNotifications()。
一种方法是设置 scrollview 的 contentOffset。您可以在用户点击文本字段进行编辑时设置它,如下所示:
func begunEditingTextField(_ sender: UITextField) {
let point = sender(sender, to: self.contentView)
self.scrollView.setContentOffset(CGPoint(x: 0, y: point.y - self.view.frame.height*0.1), animated: true)
}
注意我添加了一个 space 屏幕高度的 10% 作为填充。
对于 UITextView 它不起作用,所以我使用 contentOffset.
Swift 5
extension SummaryViewController {
private func registerKeyboardNotifications() {
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(_:)), name: UIControl.keyboardWillShowNotification, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide(_:)), name: UIControl.keyboardWillHideNotification, object: nil)
}
@objc func keyboardWillShow(_ notification: Notification) {
guard let keyboardFrameValue = notification.userInfo?[UIResponder.keyboardFrameBeginUserInfoKey] as? NSValue else { return }
let keyboardFrame = view.convert(keyboardFrameValue.cgRectValue, from: nil)
scrollView.contentOffset = CGPoint(x: 0, y: keyboardFrame.size.height)
}
@objc func keyboardWillHide(_ notification: Notification) {
scrollView.contentOffset = .zero
}
}
我有一个扩展程序可以向上滚动 scrollView,因此它不会覆盖 UITextField,但是对于 UITextView 它不会向上滚动。扩展名如下所示:
extension SummaryViewController {
///Register for keyboard willHide willShow notifiication
func registerKeyboardNotifications() {
NotificationCenter.default.addObserver(self,
selector: #selector(SummaryViewController.keyboardNotification(notification:)),
name: UIResponder.keyboardWillChangeFrameNotification, object: nil)
}
@objc func keyboardNotification(notification: NSNotification) {
if let userInfo = notification.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.curveEaseInOut.rawValue
let animationCurve: UIView.AnimationOptions = UIView.AnimationOptions(rawValue: animationCurveRaw)
if (endFrame?.origin.y)! >= UIScreen.main.bounds.size.height {
//close keyboard
scrollView.contentInset = .zero
} else {
//open keyboard
let height: CGFloat = (notification.userInfo![UIResponder.keyboardFrameEndUserInfoKey] as? CGRect)!.size.height
scrollView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: height, right: 0)
}
UIView.animate(withDuration: duration,
delay: TimeInterval(0),
options: animationCurve,
animations: { self.view.layoutIfNeeded() },
completion: nil)
}
}
}
我在 viewDidLoad 中调用 registerKeyboardNotifications()。
一种方法是设置 scrollview 的 contentOffset。您可以在用户点击文本字段进行编辑时设置它,如下所示:
func begunEditingTextField(_ sender: UITextField) {
let point = sender(sender, to: self.contentView)
self.scrollView.setContentOffset(CGPoint(x: 0, y: point.y - self.view.frame.height*0.1), animated: true)
}
注意我添加了一个 space 屏幕高度的 10% 作为填充。
对于 UITextView 它不起作用,所以我使用 contentOffset.
Swift 5
extension SummaryViewController {
private func registerKeyboardNotifications() {
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(_:)), name: UIControl.keyboardWillShowNotification, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide(_:)), name: UIControl.keyboardWillHideNotification, object: nil)
}
@objc func keyboardWillShow(_ notification: Notification) {
guard let keyboardFrameValue = notification.userInfo?[UIResponder.keyboardFrameBeginUserInfoKey] as? NSValue else { return }
let keyboardFrame = view.convert(keyboardFrameValue.cgRectValue, from: nil)
scrollView.contentOffset = CGPoint(x: 0, y: keyboardFrame.size.height)
}
@objc func keyboardWillHide(_ notification: Notification) {
scrollView.contentOffset = .zero
}
}