[英]How to manage UITextField move up when the keyboard is present - in case of multiple textFields are present?
这是我的视图控制器。
当键盘覆盖屏幕底部的 textFields 时,我试图将 textFields 向上移动。 这是我完成的代码:
override func viewDidLoad() {
super.viewDidLoad()
txtFName.delegate = self
txtLName.delegate = self
txtCompany.delegate = self
txtStreet1.delegate = self
txtStreet2.delegate = self
txtTown.delegate = self
txtPin.delegate = self
txtPhone.delegate = self
txtEmail.delegate = self
NotificationCenter.default.addObserver(
self,
selector: #selector(self.keyBoardWillChange(notification:)),
name: UIResponder.keyboardWillShowNotification, object: nil)
NotificationCenter.default.addObserver(
self,
selector: #selector(self.keyBoardWillChange(notification:)),
name: UIResponder.keyboardWillHideNotification, object: nil)
NotificationCenter.default.addObserver(
self,
selector: #selector(self.keyBoardWillChange(notification:)),
name: UIResponder.keyboardWillChangeFrameNotification, object: nil)
deinit {
NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardWillShowNotification, object: nil)
NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardWillHideNotification, object: nil)
NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardWillChangeFrameNotification, object: nil)
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
print("Return Tapped")
txtFName.resignFirstResponder()
txtLName.resignFirstResponder()
txtCompany.resignFirstResponder()
txtStreet1.resignFirstResponder()
txtStreet2.resignFirstResponder()
txtTown.resignFirstResponder()
txtPin.resignFirstResponder()
txtPhone.resignFirstResponder()
txtEmail.resignFirstResponder()
view.frame.origin.y = 0
return true
}
@objc func keyBoardWillChange(notification: Notification) {
print("Keyboard will show: \(notification.name.rawValue)")
view.frame.origin.y = -250
}
现在,当我点击任何 textFields 时,整个视图都在向上移动。 “txtFName”、“txtLName”.. 这些文本字段不可见。
我只想在点击“txtPin”、“txtPhone”、“txtEmail”时向上移动视图。 即使出现键盘,其余文本字段也将保留在默认位置。
所需的更改是什么?
通常,您可以在文本字段上使用isFirstResponder
属性。 如果为 true,则表示这是您希望在开始编辑时关注并向上移动的文本字段。
@objc private func keyBoardWillChange(notification: Notification) {
let possibleTextFields: [UITextField] = [txtLName, txtCompany, txtStreet1, txtStreet2, txtTown, txtPin, txtPhone, txtEmail]
let focusedTextField: UITextField? = possibleTextFields.first { $0.isFirstResponder }
...
}
现在,您仍然需要计算移动视图所需的偏移量
获取键盘框架:
guard let info = notification.userInfo else { return }
guard let value: NSValue = info[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue else { return }
let newFrame = value.cgRectValue
计算差异
有一些工具可以检查框架,允许您将框架转换为不同的坐标系(视图)
private func getVerticalDifference(keyboardFrame: CGRect, viewToFocus: UIView, panel: UIView) -> CGFloat {
let keyboardInPanel = panel.convert(keyboardFrame, from: nil)
let viewInPanel = panel.convert(viewToFocus.bounds, from: viewToFocus)
return viewInPanel.maxY - keyboardInPanel.minY
}
我建议您将视图控制器的视图用于panel
参数,它应该是未更改的内容(在您当前的代码中不是这种情况。避免更改视图控制器视图的框架)。
应用差异:
为了应用差异,我建议您使用约束。 将所有文本字段放在一个“面板”视图中。 此视图最好也放入滚动视图中,以便用户可以在较小的设备上滚动浏览它。 现在面板(或滚动视图)可以对视图控制器具有低优先级(例如 500)底部约束。 然后另一个高优先级底部约束设置为greaterThan
意味着底部将固定为“大于X”,其中X 可以稍后设置。
现在,您可以从这个greaterThan
约束greaterThan
一个出口拖到您的代码中。 然后你需要做的就是
bottomConstraintOutlet.constant = max(0.0, getVerticalDifference(...))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.