仅当键盘阻止 UITextField / UITextView 时才向上移动 UIView
Posted
技术标签:
【中文标题】仅当键盘阻止 UITextField / UITextView 时才向上移动 UIView【英文标题】:Moving UIView up only when the keyboard blocks the UITextField / UITextView 【发布时间】:2021-11-30 20:11:48 【问题描述】:这已经被问过几次了:1234
这些线程没有提供我正在寻找的解决方案,并且随着 Swift 5 的发布而变得有点过时,所以我在下面发布了我的解决方案。
【问题讨论】:
【参考方案1】:我建议使用 IQKeyboardManagerSwift(或用 ObjC 编写的 IQKeyboardManager)库,您可以使用 cocoapods 安装该库,链接中包含所有教程。对我来说,定制解决方案效果更好。这是该库的 2 个版本,ObjC 和 Swift:
Swift 版本:https://cocoapods.org/pods/IQKeyboardManagerSwift
ObjC 版本:https://cocoapods.org/pods/IQKeyboardManager
【讨论】:
【参考方案2】:这是我目前的解决方案:
import UIKit
// For UITextViews, exact same code, but using UITextViewDelegate
class viewController: UIViewController, UITextFieldDelegate
@IBOutlet weak var textField: UITextField!
// Keeps track of our editing frame
// Kept it as a CGRect so that it can work with both UITextFields and UITextViews
var editingFrame: CGRect?
override func viewDidLoad()
super.viewDidLoad()
// Set the delegate for the textField(s)
textField.delegate = self
// Add notification observers for keyboard
NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillChangeFrame(notification:)), name: UIResponder.keyboardWillChangeFrameNotification, object: nil)
func textFieldDidBeginEditing(_ textField: UITextField)
editingFrame = textField.frame
// This is the bit that is important, especially if you have
// your textfield inside another view (UIStackViews for example)
// The loop essentially goes through each successive superview the textfield has
// and redefines the centre in that superview's frame of reference
var currentView: UIView? = textField.superview
while currentView != nil
editingFrame?.origin.x += currentView?.frame.origin.x ?? CGFloat(0.0)
editingFrame?.origin.y += currentView?.frame.origin.y ?? CGFloat(0.0)
currentView = currentView?.superview
func textFieldShouldEndEditing(_ textField: UITextField) -> Bool
editingFrame = nil
return true
func textFieldShouldReturn(_ textField: UITextField) -> Bool
view.endEditing(true)
return true
@objc func keyboardWillChangeFrame(notification: Notification)
if let editingFrame = editingFrame
if let keyboardSize = (notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect)
let offset = editingFrame.maxY - keyboardSize.minY
if offset > self.view.frame.origin.y
self.view.frame.origin.y -= offset
else
if self.view.frame.origin.y != 0
self.view.frame.origin.y = 0
else
if self.view.frame.origin.y != 0
self.view.frame.origin.y = 0
@objc func endEditingTextFields()
view.endEditing(true)
【讨论】:
以上是关于仅当键盘阻止 UITextField / UITextView 时才向上移动 UIView的主要内容,如果未能解决你的问题,请参考以下文章
TextField 没有被键盘顺利推上,就像在 Whatsapp 和环聊中一样