我有一个应用,它在视图的下半部分有一个文本框。 这意味着当我在文本框中输入时,键盘会覆盖文本框。
我如何在打字时向上移动视图,这样我就可以看到我键入的内容,然后在键盘消失时将它移回原来的位置?
我到处都看了,但所有的解似乎都在Obj-C中,我还不能完全转换。
任何帮助都将不胜感激。
我有一个应用,它在视图的下半部分有一个文本框。 这意味着当我在文本框中输入时,键盘会覆盖文本框。
我如何在打字时向上移动视图,这样我就可以看到我键入的内容,然后在键盘消失时将它移回原来的位置?
我到处都看了,但所有的解似乎都在Obj-C中,我还不能完全转换。
任何帮助都将不胜感激。
当前回答
Swift 4中的Simpelst方法
import UIKit
class ViewController: UIViewController, UITextFieldDelegate {
@IBOutlet var myTextField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow), name: .UIKeyboardWillShow, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillHide), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
myTextField.resignFirstResponder()
}
func keyboardWillShow(notification: NSNotification) {
// let duration = notification.userInfo?[UIKeyboardAnimationDurationUserInfoKey]
// print("duration",duration)
if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue {
let keyboardHeight : Int = Int(keyboardSize.height)
print("keyboardWillShow",keyboardHeight)
if let height = UserDefaults.standard.value(forKey: "keyboardHeight") as? (Int) {
moveTextField(myTextField, moveDistance: -height as Int, moveDuration: 0.43, up: true)
}else{
UserDefaults.standard.set(keyboardHeight, forKey: "keyboardHeight")
moveTextField(myTextField, moveDistance: -keyboardHeight, moveDuration: 0.43, up: true)
}
}
}
func keyboardWillHide(notification: NSNotification){
if let height = UserDefaults.standard.value(forKey: "keyboardHeight") as? (Int) {
moveTextField(myTextField, moveDistance: -height as Int, moveDuration: 0.25, up: false)
}
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
textField.resignFirstResponder()
return true
}
func moveTextField(_ textField: UITextField, moveDistance: Int, moveDuration: Double, up: Bool) {
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()
}
}
你也可以上下移动只有UITextFiled而不是整个屏幕(UIView)。 用这种方法。
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillChange), name: .UIKeyboardWillChangeFrame, object: nil)
And
@objc func keyboardWillChange(notification: NSNotification) {
let duration = notification.userInfo![UIKeyboardAnimationDurationUserInfoKey] as! Double
let curve = notification.userInfo![UIKeyboardAnimationCurveUserInfoKey] as! UInt
let curFrame = (notification.userInfo![UIKeyboardFrameBeginUserInfoKey] as! NSValue).cgRectValue
let targetFrame = (notification.userInfo![UIKeyboardFrameEndUserInfoKey] as! NSValue).cgRectValue
let deltaY = targetFrame.origin.y - curFrame.origin.y
UIView.animateKeyframes(withDuration: duration, delay: 0.0, options: UIViewKeyframeAnimationOptions(rawValue: curve), animations: {
self.textField.frame.origin.y+=deltaY
},completion: nil)
}
其他回答
验证的答案没有考虑到文本字段的位置,并有一些错误(双位移,永远不会回到主位置,位移即使文本字段是在视图的顶部…)
这个想法是:
获取焦点TextField的Y的绝对位置 来获取键盘高度 来获取屏幕高度 然后计算键盘位置和文本框之间的距离(如果< 0 ->向上移动视图) 使用UIView。而不是UIView.frame.origin.y -= ..,因为用UIView更容易回到原来的位置。变换= .identity
然后,我们将能够移动视图,只有在必要和特定的位移,以便有聚焦texField刚刚超过键盘
代码如下:
斯威夫特4
class ViewController: UIViewController, UITextFieldDelegate {
var textFieldRealYPosition: CGFloat = 0.0
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(VehiculeViewController.keyboardWillShow), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(VehiculeViewController.keyboardWillHide), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
// Delegate all textfields
}
@objc func keyboardWillShow(notification: NSNotification) {
if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue {
let distanceBetweenTextfielAndKeyboard = self.view.frame.height - textFieldRealYPosition - keyboardSize.height
if distanceBetweenTextfielAndKeyboard < 0 {
UIView.animate(withDuration: 0.4) {
self.view.transform = CGAffineTransform(translationX: 0.0, y: distanceBetweenTextfielAndKeyboard)
}
}
}
}
@objc func keyboardWillHide(notification: NSNotification) {
UIView.animate(withDuration: 0.4) {
self.view.transform = .identity
}
}
func textFieldDidBeginEditing(_ textField: UITextField) {
textFieldRealYPosition = textField.frame.origin.y + textField.frame.height
//take in account all superviews from textfield and potential contentOffset if you are using tableview to calculate the real position
}
}
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()
}
我们对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
}
}
}
我做了一个椰子荚来简化问题:
https://github.com/xtrinch/KeyboardLayoutHelper
如何使用:
做一个自动布局底部约束,在模块KeyboardLayoutHelper中给它一个KeyboardLayoutConstraint类,pod将做必要的工作来增加它,以适应出现和消失的键盘。关于如何使用它(我做了两个:一个scrollView内的textFields,和垂直居中的textFields与两个基本视图-登录和注册)的例子项目。
底部布局约束可以是容器视图,textField本身,任何你能想到的。