Существует вид с двумя UITextFields, и вид перемещается в соответствии с высотой клавиатуры. Однако перемещение представления не является идеальным, если хотя бы для одного текстового поля свойство isSecureTextEntry имеет значение true. Это заметно при перемещении между текстовыми полями. Вид перемещается вниз один раз и мгновенно возвращается. Это потому, что высота клавиатуры меняется на мгновение. Я думаю, что это вопрос показа / скрытия QuickTypeBar. Итак, как устранить этот эффект и контролировать движение вида?
Ниже приведен весь код. Это может не выглядеть прямо в симуляторе. Потому что панель QuickType не отображается. Это происходит на iPhone X iOS13.3.1.
Спасибо.
import UIKit
class ViewController: UIViewController {
public var boardView: UIView!
public var usernameTextField: UITextField!
public var passwordTextField: UITextField!
public var boardViewBottomAnchorConstraint: NSLayoutConstraint!
public var boardViewBottomAnchorConstraintConstant: CGFloat = -220
public var offset: CGFloat = 16.0
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .darkGray
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(_:)), name: UIResponder.keyboardWillShowNotification, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide(_:)), name: UIResponder.keyboardWillHideNotification, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillChangeFrame(_:)), name: UIResponder.keyboardWillChangeFrameNotification, object: nil)
var constraints = [NSLayoutConstraint]()
let boardView = UIView()
boardView.backgroundColor = .brown
boardView.layer.cornerRadius = 16.0
boardView.translatesAutoresizingMaskIntoConstraints = false
boardViewBottomAnchorConstraint = boardView.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: boardViewBottomAnchorConstraintConstant)
constraints.append(boardView.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 16))
constraints.append(boardViewBottomAnchorConstraint)
constraints.append(boardView.rightAnchor.constraint(equalTo: view.rightAnchor, constant: -16))
view.addSubview(boardView)
self.boardView = boardView
let usernameTextField = UITextField()
usernameTextField.backgroundColor = .white
usernameTextField.delegate = self
usernameTextField.returnKeyType = .next
usernameTextField.textContentType = .username
usernameTextField.placeholder = "USERNAME TEXTFIELD"
usernameTextField.translatesAutoresizingMaskIntoConstraints = false
constraints.append(usernameTextField.heightAnchor.constraint(equalToConstant: 56))
constraints.append(usernameTextField.topAnchor.constraint(equalTo: boardView.topAnchor, constant: 100))
constraints.append(usernameTextField.leftAnchor.constraint(equalTo: boardView.leftAnchor, constant: 24))
constraints.append(usernameTextField.rightAnchor.constraint(equalTo: boardView.rightAnchor, constant: -24))
boardView.addSubview(usernameTextField)
self.usernameTextField = usernameTextField
let passwordTextField = UITextField()
passwordTextField.backgroundColor = .white
passwordTextField.delegate = self
passwordTextField.returnKeyType = .go
passwordTextField.textContentType = .password
passwordTextField.placeholder = "PASSWORD TEXTFIELD"
passwordTextField.translatesAutoresizingMaskIntoConstraints = false
constraints.append(passwordTextField.heightAnchor.constraint(equalToConstant: 56))
constraints.append(passwordTextField.topAnchor.constraint(equalTo: usernameTextField.bottomAnchor, constant: 50))
constraints.append(passwordTextField.leftAnchor.constraint(equalTo: boardView.leftAnchor, constant: 24))
constraints.append(passwordTextField.bottomAnchor.constraint(equalTo: boardView.bottomAnchor, constant: -100))
constraints.append(passwordTextField.rightAnchor.constraint(equalTo: boardView.rightAnchor, constant: -24))
boardView.addSubview(passwordTextField)
self.passwordTextField = passwordTextField
NSLayoutConstraint.activate(constraints)
let tap = UITapGestureRecognizer(target: view, action: #selector(UIView.endEditing(_:)))
view.addGestureRecognizer(tap)
// false is the ideal move. If true, the view moves violently.
passwordTextField.isSecureTextEntry = true
}
}
extension ViewController {
@objc
public func keyboardWillShow(_ notification: Notification) { print("WILL SHOW")
updateConstraints(notification)
}
@objc
public func keyboardWillHide(_ notification: Notification) { print("WILL HIDE")
boardViewBottomAnchorConstraint.constant = boardViewBottomAnchorConstraintConstant
view.layoutIfNeeded()
}
@objc
public func keyboardWillChangeFrame(_ notification: Notification) { print("WILL CHANGE FRAME")
updateConstraints(notification)
}
private func updateConstraints(_ notification: Notification) {
guard
let toFrame = notification.userInfo?[UIApplication.keyboardFrameEndUserInfoKey] as? CGRect,
let fromFrame = notification.userInfo?[UIApplication.keyboardFrameBeginUserInfoKey] as? CGRect else { return }
print(fromFrame); print(toFrame);
let constant = -toFrame.size.height - offset
boardViewBottomAnchorConstraint.constant = constant
view.layoutIfNeeded()
}
}
extension ViewController: UITextFieldDelegate {
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
if textField == usernameTextField {
passwordTextField.becomeFirstResponder()
} else {
passwordTextField.resignFirstResponder()
}
return true
}
}