我有一个应用,它在视图的下半部分有一个文本框。 这意味着当我在文本框中输入时,键盘会覆盖文本框。
我如何在打字时向上移动视图,这样我就可以看到我键入的内容,然后在键盘消失时将它移回原来的位置?
我到处都看了,但所有的解似乎都在Obj-C中,我还不能完全转换。
任何帮助都将不胜感激。
我有一个应用,它在视图的下半部分有一个文本框。 这意味着当我在文本框中输入时,键盘会覆盖文本框。
我如何在打字时向上移动视图,这样我就可以看到我键入的内容,然后在键盘消失时将它移回原来的位置?
我到处都看了,但所有的解似乎都在Obj-C中,我还不能完全转换。
任何帮助都将不胜感激。
当前回答
我们对KeyboardWillHideNotification的定义做了一些改变。
此解决方案适用于Swift 4.2:
NotificationCenter.default.addObserver(self, selector: #selector(ViewController.keyboardWillShow), name: UIResponder.keyboardWillShowNotification, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(ViewController.keyboardWillHide), name: UIResponder.keyboardWillHideNotification, object: nil)
@objc func keyboardWillShow(_ notification:Notification) {
if let keyboardSize = (notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue {
self.view.frame.origin.y -= keyboardSize.height
}
}
@objc func keyboardWillHide(_ notification:Notification) {
if let keyboardSize = (notification.userInfo?[UIResponder.keyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue {
self.view.frame.origin.y += keyboardSize.height
}
}
其他回答
swift 3.0插入在viewDidLoad(),这->
{
view addSubview (Your_messageInputConteinerView)。
view.addConstraintWithFormat(format: "H:|[v0]|", views:Your_messageInputConteinerView)
view.addConstraintWithFormat(format: "V:[v0(48)]", views:Your_messageInputConteinerView)
addobserver (self, selector: #selector(handleKeyboardNotification(notification:))), name: NSNotification.Name。对象:nil)
addobserver (self, selector: #selector(handleKeyboardNotification(notification:))),名称:.UIKeyboardWillHide,对象:nil)
bottomConstraint = NSLayoutConstraint(item: Your_messageInputConteinerView, attribute: .bottom, relatedBy: .equal, toItem: view, attribute: .bottom, multiplier: 1, constant: 0)
view.addConstraint(bottomConstraint!)
}
func handleKeyboardNotification(通知:通知){
if let userInfo = notification.userInfo {
if let keyBoardFrame = (userInfo[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue{
print(keyBoardFrame)
if bottomConstraint?.constant != CGFloat(0) {
bottomConstraint?.constant = 0
return
}
bottomConstraint?.constant = -keyBoardFrame.height
or
self.view.frame.origin.y = -keyBoardFrame.height
}
}
}
func keyboardWillShow(notification: NSNotification) {
if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue() {
self.view.frame.origin.y = self.view.frame.height - (self.view.frame.height + keyboardSize.height)
}
}
func keyboardWillHide(notification: NSNotification) {
self.view.frame.origin.y = 0
}
它必须更加稳定
在这个线程中,一个流行的答案使用了以下代码:
func keyboardWillShow(sender: NSNotification) {
self.view.frame.origin.y -= 150
}
func keyboardWillHide(sender: NSNotification) {
self.view.frame.origin.y += 150
}
用一个静态量来抵消你的视图有一个明显的问题。它在一个设备上看起来很好,但在任何其他尺寸配置上看起来都很糟糕。您需要获取键盘高度并将其用作偏移值。
下面是一种适用于所有设备的解决方案,它可以处理用户在输入时隐藏预测文本字段的边缘情况。
解决方案
下面需要注意的是,我们将self.view.window作为对象参数传入。这将为我们提供来自键盘的数据,比如它的高度!
@IBOutlet weak var messageField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillShow:"), name:UIKeyboardWillShowNotification, object: self.view.window)
NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillHide:"), name:UIKeyboardWillHideNotification, object: self.view.window)
}
func keyboardWillHide(sender: NSNotification) {
let userInfo: [NSObject : AnyObject] = sender.userInfo!
let keyboardSize: CGSize = userInfo[UIKeyboardFrameBeginUserInfoKey]!.CGRectValue.size
self.view.frame.origin.y += keyboardSize.height
}
我们将使它在所有设备上看起来都很漂亮,并处理用户添加或删除预测文本字段的情况。
func keyboardWillShow(sender: NSNotification) {
let userInfo: [NSObject : AnyObject] = sender.userInfo!
let keyboardSize: CGSize = userInfo[UIKeyboardFrameBeginUserInfoKey]!.CGRectValue.size
let offset: CGSize = userInfo[UIKeyboardFrameEndUserInfoKey]!.CGRectValue.size
if keyboardSize.height == offset.height {
UIView.animateWithDuration(0.1, animations: { () -> Void in
self.view.frame.origin.y -= keyboardSize.height
})
} else {
UIView.animateWithDuration(0.1, animations: { () -> Void in
self.view.frame.origin.y += keyboardSize.height - offset.height
})
}
}
删除观察者
不要忘记在离开视图之前删除您的观察器,以防止传输不必要的消息。
override func viewWillDisappear(animated: Bool) {
NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardWillShowNotification, object: self.view.window)
NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardWillHideNotification, object: self.view.window)
}
根据评论中的问题更新:
如果你有两个或更多的文本字段,你可以检查你的view.frame.origin.y是否为零。
func keyboardWillShow(sender: NSNotification) {
let userInfo: [NSObject : AnyObject] = sender.userInfo!
let keyboardSize: CGSize = userInfo[UIKeyboardFrameBeginUserInfoKey]!.CGRectValue.size
let offset: CGSize = userInfo[UIKeyboardFrameEndUserInfoKey]!.CGRectValue.size
if keyboardSize.height == offset.height {
if self.view.frame.origin.y == 0 {
UIView.animateWithDuration(0.1, animations: { () -> Void in
self.view.frame.origin.y -= keyboardSize.height
})
}
} else {
UIView.animateWithDuration(0.1, animations: { () -> Void in
self.view.frame.origin.y += keyboardSize.height - offset.height
})
}
print(self.view.frame.origin.y)
}
当打开键盘时,它100%完美地回答了所有人的更新表视图高度
对于Swift4.2
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(RecipeVC.keyboardWillShow), name: UIResponder.keyboardWillShowNotification, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(RecipeVC.keyboardWillHide), name: UIResponder.keyboardWillHideNotification, object: nil)
}
@objc func keyboardWillShow(notification: NSNotification) {
if ((notification.userInfo?[UIResponder.keyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue) != nil {
var userInfo = notification.userInfo!
var keyboardFrame:CGRect = (userInfo[UIResponder.keyboardFrameEndUserInfoKey] as! NSValue).cgRectValue
keyboardFrame = self.view.convert(keyboardFrame, from: nil)
var contentInset:UIEdgeInsets = self.tbl.contentInset
contentInset.bottom = keyboardFrame.size.height
self.tbl.contentInset = contentInset
}
}
@objc func keyboardWillHide(notification: NSNotification) {
if ((notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue) != nil {
let contentInset:UIEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
self.tbl.contentInset = contentInset
}
}
Swift3.2
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(RecipeVC.keyboardWillShow), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(RecipeVC.keyboardWillHide), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
}
func keyboardWillShow(notification: NSNotification) {
if ((notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue) != nil {
//self.view.frame.origin.y -= keyboardSize.height
var userInfo = notification.userInfo!
var keyboardFrame:CGRect = (userInfo[UIKeyboardFrameEndUserInfoKey] as! NSValue).cgRectValue
keyboardFrame = self.view.convert(keyboardFrame, from: nil)
var contentInset:UIEdgeInsets = self.tbl.contentInset
contentInset.bottom = keyboardFrame.size.height
self.tbl.contentInset = contentInset
}
}
func keyboardWillHide(notification: NSNotification) {
if ((notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue) != nil {
let contentInset:UIEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
self.tbl.contentInset = contentInset
}
}
斯威夫特5.0:
经过4-5个小时的战斗,我得到了一个简单的扩展UIViewController与简单的代码,就像魅力
*当TextField在键盘上方时,视图不应该移动
*不需要设置常量值为NSLayoutConstraint
*无需第三方库
*无需动画代码
*适用于tableview
*这适用于自动布局/自动调整大小
extension UIViewController {
func addKeyboardObserver() {
NotificationCenter.default.addObserver(self, selector: #selector(keyboardNotifications(notification:)),
name: UIResponder.keyboardWillChangeFrameNotification,
object: nil)
}
func removeKeyboardObserver(){
NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardWillChangeFrameNotification, object: nil)
}
// This method will notify when keyboard appears/ dissapears
@objc func keyboardNotifications(notification: NSNotification) {
var txtFieldY : CGFloat = 0.0 //Using this we will calculate the selected textFields Y Position
let spaceBetweenTxtFieldAndKeyboard : CGFloat = 5.0 //Specify the space between textfield and keyboard
var frame = CGRect(x: 0, y: 0, width: 0, height: 0)
if let activeTextField = UIResponder.currentFirst() as? UITextField ?? UIResponder.currentFirst() as? UITextView {
// Here we will get accurate frame of textField which is selected if there are multiple textfields
frame = self.view.convert(activeTextField.frame, from:activeTextField.superview)
txtFieldY = frame.origin.y + frame.size.height
}
if let userInfo = notification.userInfo {
// here we will get frame of keyBoard (i.e. x, y, width, height)
let keyBoardFrame = (userInfo[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue
let keyBoardFrameY = keyBoardFrame!.origin.y
let keyBoardFrameHeight = keyBoardFrame!.size.height
var viewOriginY: CGFloat = 0.0
//Check keyboards Y position and according to that move view up and down
if keyBoardFrameY >= UIScreen.main.bounds.size.height {
viewOriginY = 0.0
} else {
// if textfields y is greater than keyboards y then only move View to up
if txtFieldY >= keyBoardFrameY {
viewOriginY = (txtFieldY - keyBoardFrameY) + spaceBetweenTxtFieldAndKeyboard
//This condition is just to check viewOriginY should not be greator than keyboard height
// if its more than keyboard height then there will be black space on the top of keyboard.
if viewOriginY > keyBoardFrameHeight { viewOriginY = keyBoardFrameHeight }
}
}
//set the Y position of view
self.view.frame.origin.y = -viewOriginY
}
}
}
添加这个扩展的UIResponder得到哪个TextField被选中
extension UIResponder {
static weak var responder: UIResponder?
static func currentFirst() -> UIResponder? {
responder = nil
UIApplication.shared.sendAction(#selector(trap), to: nil, from: nil, for: nil)
return responder
}
@objc private func trap() {
UIResponder.responder = self
}
}
然后在你的任何ViewController中使用这个
override func viewWillAppear(_ animated: Bool) {
self.addKeyboardObserver()
}
override func viewWillDisappear(_ animated: Bool) {
self.removeKeyboardObserver()
}
在func viewWillAppear中注册这个通知(_ animated: Bool) 在func中注销此通知viewWillDisappear(_ animated:Bool) 下载演示文件