![](/img/trans.png)
[英]How can I make a UITextField move up when the keyboard is present - on starting to edit?
[英]How to make UITextField move up when keyboard is present?
如何防止UITextField
被键盘隐藏?
我假设这发生在UIViewController
。 如果是这样,您可以设置在键盘显示/隐藏时调用以下两个函数,并在它们的块中做出适当的响应。
设置UIViewController
:
class ViewController: UIViewController, UITextFieldDelegate... {
var frameView: UIView!
首先,在viewDidLoad()
:
override func viewDidLoad() {
self.frameView = UIView(frame: CGRect(x: 0, y: 0, width: self.view.bounds.width, height: self.view.bounds.height))
// Keyboard stuff.
let center: NotificationCenter = NotificationCenter.default
center.addObserver(self, selector: #selector(keyboardWillShow(notification:)), name: UIResponder.keyboardWillShowNotification, object: nil)
center.addObserver(self, selector: #selector(keyboardWillHide(notification:)), name: UIResponder.keyboardWillHideNotification, object: nil)
}
然后实现下面两个函数来响应你上面viewDidLoad()
定义的NotificationCenter
函数。 我给你一个移动整个视图的例子,但你也可以只为UITextField
设置动画。
@objc func keyboardWillShow(notification: NSNotification) {
let info:NSDictionary = notification.userInfo! as NSDictionary
let keyboardSize = (info[UIResponder.keyboardFrameBeginUserInfoKey] as! NSValue).cgRectValue
let keyboardHeight: CGFloat = keyboardSize.height
let _: CGFloat = info[UIResponder.keyboardAnimationDurationUserInfoKey] as! NSNumber as! CGFloat
UIView.animate(withDuration: 0.25, delay: 0.25, options: .curveEaseInOut, animations: {
self.frameView.frame = CGRect(x: 0, y: (self.frameView.frame.origin.y - keyboardHeight), width: self.view.bounds.width, height: self.view.bounds.height)
}, completion: nil)
}
@objc func keyboardWillHide(notification: NSNotification) {
let info: NSDictionary = notification.userInfo! as NSDictionary
let keyboardSize = (info[UIResponder.keyboardFrameBeginUserInfoKey] as! NSValue).cgRectValue
let keyboardHeight: CGFloat = keyboardSize.height
let _: CGFloat = info[UIResponder.keyboardAnimationDurationUserInfoKey] as! NSNumber as! CGFloat
UIView.animate(withDuration: 0.25, delay: 0.25, options: .curveEaseInOut, animations: {
self.frameView.frame = CGRect(x: 0, y: (self.frameView.frame.origin.y + keyboardHeight), width: self.view.bounds.width, height: self.view.bounds.height)
}, completion: nil)
}
离开视图时不要忘记删除通知
override func viewWillDisappear(_ animated: Bool) {
NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardWillShowNotification, object: nil)
NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardWillHideNotification, object: nil)
}
这是 Swift 中的简单解决方案。 我翻译了一些过去对我有用的 Objective-C 代码。
func textFieldDidBeginEditing(textField: UITextField) { // became first responder
//move textfields up
let myScreenRect: CGRect = UIScreen.mainScreen().bounds
let keyboardHeight : CGFloat = 216
UIView.beginAnimations( "animateView", context: nil)
var movementDuration:NSTimeInterval = 0.35
var needToMove: CGFloat = 0
var frame : CGRect = self.view.frame
if (textField.frame.origin.y + textField.frame.size.height + /*self.navigationController.navigationBar.frame.size.height + */UIApplication.sharedApplication().statusBarFrame.size.height > (myScreenRect.size.height - keyboardHeight)) {
needToMove = (textField.frame.origin.y + textField.frame.size.height + /*self.navigationController.navigationBar.frame.size.height +*/ UIApplication.sharedApplication().statusBarFrame.size.height) - (myScreenRect.size.height - keyboardHeight);
}
frame.origin.y = -needToMove
self.view.frame = frame
UIView.commitAnimations()
}
func textFieldDidEndEditing(textField: UITextField) {
//move textfields back down
UIView.beginAnimations( "animateView", context: nil)
var movementDuration:NSTimeInterval = 0.35
var frame : CGRect = self.view.frame
frame.origin.y = 0
self.view.frame = frame
UIView.commitAnimations()
}
Swift 4 的代码,非常简单,而不是使用NSNotificationCenter之类的很多东西,然后计算所有东西的高度和制作条件使这个变得更加复杂,
执行此操作的简单方法如下所示,它将向上移动视图。
func textFieldDidBeginEditing(_ textField: UITextField) {
moveTextField(textfield: textField, moveDistance: -250, up: true)
}
func textFieldDidEndEditing(_ textField: UITextField) {
moveTextField(textfield: textField, moveDistance: -250, up: false)
}
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()
}
您可以根据文本字段的位置更改 -250 值。
如果您使用UIScrollView
或其任何子类,例如UITableView
,您还可以操作contentInset
属性。 这样你就不必弄乱frame
、 bounds
、 NSLayoutConstraint
或NSLayoutAnchor
。
func keyboardWillShow(notification: Notification) {
let info = notification.userInfo!
let keyboardSize = (info[UIKeyboardFrameBeginUserInfoKey] as! NSValue).cgRectValue
let keyboardHeight: CGFloat = keyboardSize.height
let duration = info[UIKeyboardAnimationDurationUserInfoKey] as! TimeInterval
UIView.animate(withDuration: duration, delay: 0, options: UIViewAnimationOptions.curveEaseInOut, animations: {
self.tableView?.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: keyboardHeight, right: 0)
}, completion: nil)
}
func keyboardWillHide(notification: Notification) {
let info = notification.userInfo!
let duration = info[UIKeyboardAnimationDurationUserInfoKey] as! TimeInterval
UIView.animate(withDuration: duration, delay: 0, options: UIViewAnimationOptions.curveEaseInOut, animations: {
self.tableView?.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
}, completion: nil)
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(notification:)), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide(notification:)), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillShow, object: nil)
NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillHide, object: nil)
}
斯威夫特 3.0
var activeField: UITextField?
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(ProfileViewController.keyboardWillShow), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(ProfileViewController.keyboardWillHide), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
}
func textFieldDidBeginEditing(_ textField: UITextField){
activeField = textField
}
func textFieldDidEndEditing(_ textField: UITextField){
activeField = nil
}
func keyboardWillShow(notification: NSNotification) {
if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue {
if (self.activeField?.frame.origin.y)! >= keyboardSize.height {
self.view.frame.origin.y = keyboardSize.height - (self.activeField?.frame.origin.y)!
} else {
self.view.frame.origin.y = 0
}
}
}
func keyboardWillHide(notification: NSNotification) {
self.view.frame.origin.y = 0
}
在 Swift 3 中使用此代码
override func viewDidLoad() {
super.viewDidLoad()
let center: NotificationCenter = NotificationCenter.default
center.addObserver(self, selector: #selector(RFLogInViewController.keyboardWillShow(notification:)), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
center.addObserver(self, selector: #selector(RFLogInViewController.keyboardWillHide(notification:)), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
}
func keyboardWillShow(notification: NSNotification) {
let info:NSDictionary = notification.userInfo! as NSDictionary
let keyboardSize = (info[UIKeyboardFrameBeginUserInfoKey] as! NSValue).cgRectValue
let keyboardHeight: CGFloat = keyboardSize.height
let _: CGFloat = info[UIKeyboardAnimationDurationUserInfoKey] as! NSNumber as! CGFloat
UIView.animate(withDuration: 0.25, delay: 0.25, options: .curveEaseInOut, animations: {
self.view.frame = CGRect(x: 0, y: (self.view.frame.origin.y - keyboardHeight), width: self.view.bounds.width, height: self.view.bounds.height)
}, completion: nil)
}
func keyboardWillHide(notification: NSNotification) {
let info: NSDictionary = notification.userInfo! as NSDictionary
let keyboardSize = (info[UIKeyboardFrameBeginUserInfoKey] as! NSValue).cgRectValue
let keyboardHeight: CGFloat = keyboardSize.height
let _: CGFloat = info[UIKeyboardAnimationDurationUserInfoKey] as! NSNumber as! CGFloat
UIView.animate(withDuration: 0.25, delay: 0.25, options: .curveEaseInOut, animations: {
self.view.frame = CGRect(x: 0, y: (self.view.frame.origin.y + keyboardHeight), width: self.view.bounds.width, height: self.view.bounds.height)
}, completion: nil)
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(true)
NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillShow, object: nil)
NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillHide, object: nil)
}
只需将“IQKeyboardManager”库添加到您的项目中,就完成了。 你不必做任何其他事情。 作为参考,请检查此网址。
Swift 4我已经看到了很多答案,其中很多对我来说都不起作用,因为我有一个带有大量文本字段的 UIViewController。
根据Apple 文档,我已将示例翻译为 Swift 4
您的内容需要嵌入到滚动视图中。
添加键盘何时出现或消失的通知侦听器。
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardDidShow), name: .UIKeyboardDidShow, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide), name: .UIKeyboardWillHide, object: nil)
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
NotificationCenter.default.removeObserver(self)
}
实现 UITextField 委托
func textFieldDidBeginEditing(_ textField: UITextField) {
currentTextField = textField
}
func textFieldDidEndEditing(_ textField: UITextField, reason: UITextFieldDidEndEditingReason) {
currentTextField = nil
}
选择器
@objc func keyboardDidShow(notification: NSNotification) {
print("\(logClassName): keyboardWDidShow")
let keyboardFrame = (notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as! NSValue).cgRectValue
let keyboardSize:CGSize = keyboardFrame!.size
let contentInsets:UIEdgeInsets = UIEdgeInsetsMake(0, 0, keyboardSize.height, 0)
trackScrollView.contentInset = contentInsets
trackScrollView.scrollIndicatorInsets = contentInsets
var aRect:CGRect = self.view.frame
aRect.size.height -= keyboardSize.height
if !(aRect.contains(currentTextField!.frame.origin)){
trackScrollView.scrollRectToVisible(currentTextField!.frame, animated: true)
}
}
@objc func keyboardWillHide(notification: NSNotification){
print("\(logClassName): keyboardWillHide")
let contentInsents:UIEdgeInsets = UIEdgeInsets.zero
trackScrollView.contentInset = contentInsents
trackScrollView.scrollIndicatorInsets = contentInsents
}
首先你应该有scrollview步骤1:找到键盘的高度
func keyboardWillShow(notification: NSNotification) {
if let keyboardSize = (notification.userInfo ? [UIKeyboardFrameBeginUserInfoKey] as ? NSValue) ? .cgRectValue {
let keyboardHeight = keyboardSize.height
a = keyboardHeight
}
}
第二步:绑定textfield的delegete方法
func textFieldDidBeginEditing(_ textField: UITextField) {
utility.setUserDefaultBool(value: false, key: "FrameMoveFlag") //flag
let b = view1.frame.height - textField.frame.origin.y
if (b < 350) {
view1.frame.origin.y = view1.frame.origin.y + (view1.frame.height - textField.frame.origin.y) - (a + 50)
utility.setUserDefaultBool(value: true, key: "FrameMoveFlag") //flag
}
}
func textFieldDidEndEditing(_ textField: UITextField) {
if (utility.getUserDefaultBOOLForKey(key: "FrameMoveFlag") == true) {
view1.frame.origin.y = 0
}
}
盖革答案的Swift 3代码
func textFieldDidBeginEditing(_ textField: UITextField) { // became first responder
//move textfields up
let myScreenRect: CGRect = UIScreen.main.bounds
let keyboardHeight : CGFloat = 216
UIView.beginAnimations( "animateView", context: nil)
var movementDuration:TimeInterval = 0.35
var needToMove: CGFloat = 0
var frame : CGRect = self.view.frame
if (textField.frame.origin.y + textField.frame.size.height + UIApplication.shared.statusBarFrame.size.height > (myScreenRect.size.height - keyboardHeight - 30)) {
needToMove = (textField.frame.origin.y + textField.frame.size.height + UIApplication.shared.statusBarFrame.size.height) - (myScreenRect.size.height - keyboardHeight - 30);
}
frame.origin.y = -needToMove
self.view.frame = frame
UIView.commitAnimations()
}
func textFieldDidEndEditing(_ textField: UITextField) {
//move textfields back down
UIView.beginAnimations( "animateView", context: nil)
var movementDuration:TimeInterval = 0.35
var frame : CGRect = self.view.frame
frame.origin.y = 0
self.view.frame = frame
UIView.commitAnimations()
}
如果您不想手动处理键盘的出现和消失,只需使用 UITableViewController 它将处理表格视图中的所有文本字段。
查看我的要点,我在我的案例中使用了 scrollView,但它适用于任何类型的视图,您只需删除 scrollView 部分并将其替换为您的视图。 要点的评论非常好,因此您还将了解如何处理此案例。 https://gist.github.com/Sjahriyar/916e93153a29dc602b45f29d39182352
我创建了KeyboardController
来处理键盘问题。 需要做的就是调用setUpKeyBoardListeners()
并将lastElement
设置为视图中的最后一个元素。
要点: https : //gist.github.com/espitia/ef830cf677fa1bc33ffdf16ac12d0204
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.