单击已显示键盘的第二个UITextField会错误地移动内容
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了单击已显示键盘的第二个UITextField会错误地移动内容相关的知识,希望对你有一定的参考价值。
编辑:添加了请求的方法。
更新:当我单击输入1时,将调用keyboardwillchange回调一次。当我在没有先解除键盘的情况下点击第二个输入时,由于某种原因,键盘会切换回调被称为TWICE。另外,我注意到我的代码仍在计算正确的帧。然而,似乎xcode忽略了这一点,或者只是覆盖并将事情重新置于它们最初的构造方式。
我的屏幕顶部有一些图像内容,2个文本字段,下半部分有文本视图。输入位于堆栈视图中。每当我单击文本字段/视图时,我都会将堆栈视图向上移动得足够远,以便所有输入都可见。当我关闭键盘时,堆栈视图会回到原来的位置。这很棒!当我单击一个文本字段(常规键盘)然后单击另一个文本字段(数字键盘)时,我的堆栈视图将返回原始位置,此时它根本不应移动。为了尝试修复此问题,我添加了一些布尔值来跟踪键盘是否显示并使用它来阻止我的UIKeyboardWillShow方法做任何事情。
什么是Xcode 9.1 / Swift 4,我可以阻止它发生?
旁注:我尝试使用IQKeyboardManager,但它似乎不允许我阻止顶部图像内容移动太多。
我的相关代码:
class MoodEntryVC: UIViewController, UITextFieldDelegate, UITextViewDelegate {
@IBOutlet weak var questionsStackView: UIStackView!
@IBOutlet weak var hoursTextField: UITextField!
@IBOutlet weak var locationTextField: UITextField!
@IBOutlet weak var otherInfoTextView: UITextView!
@IBOutlet weak var headerBarView: UIView!
@IBOutlet weak var bgHeaderView: UIImageView!
var currentTextField: UITextField?
var currentTextView: UITextView?
var currentBGHeaderFrame: CGRect!
var currentQuestionsStackFrame: CGRect!
var currentFieldEditing: FieldType!
var keyboardVisible: Bool = false
override func viewDidLoad() {
super.viewDidLoad()
hideKeyboardWhenTappedAround2()
locationTextField.delegate = self
hoursTextField.delegate = self
otherInfoTextView.delegate = self
currentBGHeaderFrame = bgHeaderView.frame
currentQuestionsStackFrame = questionsStackView.frame
NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillShow(_:)), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillHide(_:)), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardDidShow(_:)), name: NSNotification.Name.UIKeyboardDidShow, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillChangeFrame(_:)), name: NSNotification.Name.UIKeyboardWillChangeFrame, object: nil)
}
fileprivate func moveQuestionsAndBGHeader(_ newTopY: CGFloat, _ bgNewTopY: CGFloat) {
UIView.animate(withDuration: 0.3, delay: 0.0, options: UIViewAnimationOptions.curveEaseIn, animations: {
let newRect = CGRect(x: self.questionsStackView.frame.origin.x, y: newTopY, width: self.questionsStackView.bounds.width, height: self.questionsStackView.bounds.height)
self.questionsStackView.frame = newRect
self.bgHeaderView.frame = CGRect(x: self.bgHeaderView.frame.origin.x, y: bgNewTopY, width: self.bgHeaderView.bounds.width, height: self.bgHeaderView.bounds.height)
}, completion: nil)
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
UIView.animate(withDuration: 1.3, delay: 0.0, options: UIViewAnimationOptions.curveEaseInOut, animations: {
textField.resignFirstResponder()
}, completion: nil)
return true
}
@objc func keyboardDidShow(_ notification: NSNotification) {
keyboardVisible = true
}
@objc func keyboardWillChangeFrame(_ notification: NSNotification) {
print("keyboard will change")
}
@objc func keyboardWillShow(_ notification: NSNotification) {
if keyboardVisible {
return
}
// Get keyboard sizing
let endFrame = (notification.userInfo![UIKeyboardFrameEndUserInfoKey] as! NSValue).cgRectValue
// Get data entry view sizing
let topY = questionsStackView.frame.origin.y
let bottomY = questionsStackView.frame.height + topY
let newTopY = endFrame.origin.y - 10 - questionsStackView.frame.height
// Get bgHeaderView sizing
let bgTopY = bgHeaderView.frame.origin.y
let bgBottomY = bgHeaderView.frame.height + bgTopY
let gapToDataEntry = topY - bgBottomY
let bgNewTopY = newTopY - gapToDataEntry - bgHeaderView.frame.height
// This moves the stack view to the correct location above the keyboard
moveQuestionsAndBGHeader(newTopY, bgNewTopY)
}
@objc func keyboardWillHide(_ notification: NSNotification) {
UIView.animate(withDuration: 1.3, delay: 0.0, options: UIViewAnimationOptions.curveEaseInOut, animations: {
self.moveQuestionsAndBGHeader(self.currentQuestionsStackFrame.origin.y, self.currentBGHeaderFrame.origin.y)
self.view.endEditing(true)
}, completion: nil)
keyboardVisible = false
}
谢谢!
答案
尝试添加此方法
func textFieldDidEndEditing(textField: UITextField) {
view.endEditing(true)
}
当第一个文本字段将变为活动状态时,键盘将隐藏。类似地,当其他文本字段将变为活动状态时,键盘将显示。
以上是关于单击已显示键盘的第二个UITextField会错误地移动内容的主要内容,如果未能解决你的问题,请参考以下文章