I want to set my view bottom constrains equal to keyboard height. Keyboard is always active during lifecycle of VC.
However, when my VC is loading my view changing it's height in a strange way(as I showed in a gif)
In IB keyboardHeigthConstraint is constrains of Bottom Layout Guide Top and my View and equals to 0
@IBOutlet weak var keyboardHeigthConstraint: NSLayoutConstraint!
override func viewDidLoad() {
super.viewDidLoad()
cardNumberTextField.becomeFirstResponder()
NotificationCenter.default.addObserver(self, selector: #selector(handleKeyboardNotification), name: NSNotification.Name.UIKeyboardWillChangeFrame , object: nil)
}
func handleKeyboardNotification(notification: NSNotification) {
if let userInfo = notification.userInfo {
let keyboardFrame: CGRect = (userInfo[UIKeyboardFrameEndUserInfoKey] as! NSValue).cgRectValue
DispatchQueue.main.async {
self.keyboardHeigthConstraint.constant = keyboardFrame.size.height
self.view.layoutIfNeeded()
}
}
What could cause such strange behaviour?
There're a few problems in your code:
cardNumberTextField.becomeFirstResponder()
should be called in viewWillAppear
instead; cardNumberTextField.becomeFirstResponder()
after you subscribe for keyboard notifications; viewDidDisappear
; DispatchQueue.main.async
. I think it should help.
@IBOutlet weak var keyboardHeigthConstraint: NSLayoutConstraint!
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
NotificationCenter.default.addObserver(self, selector: #selector(handleKeyboardNotification), name: NSNotification.Name.UIKeyboardWillChangeFrame, object: nil)
cardNumberTextField.becomeFirstResponder()
}
override func viewDidDisappear(_ animated: Bool) {
NotificationCenter.default.removeObserver(self)
super.viewDidDisappear(animated)
}
func handleKeyboardNotification(notification: NSNotification) {
guard let userInfo = notification.userInfo,
let frameValue = userInfo[UIKeyboardFrameEndUserInfoKey] as? NSValue else {
return
}
let keyboardFrame = frameValue.cgRectValue
keyboardHeigthConstraint.constant = keyboardFrame.height
view.layoutIfNeeded()
}
You could also animate the height with
let keyboardDuration = (notification.userInfo?[UIKeyboardAnimationDurationUserInfoKey] as! NSNumber).doubleValue
UIView.animate(withDuration: keyboardDuration, animations: {
DispatchQueue.main.async {
self.keyboardHeigthConstraint.constant = keyboardFrame.size.height
self.view.layoutIfNeeded()
}
})
From your gif image i can see your button is jumping and that may be the problem. Try adding button's vertical constraint with the textView and your button will always be in that position. If you want to support for all devices you have to calculate that vertical constraint according to device size.
actually all answers above hadn't provide the working solution for me, but my final variant is a collaboration of all of theese answres
I suppose, that the key problem was that I decided to change the bottom constrains. When I shifted to top one, "jumping" disappeared
override func viewWillAppear(_ animated: Bool) {
cardNumberTextField.becomeFirstResponder()
NotificationCenter.default.addObserver(self, selector: #selector(handleKeyboardNotification), name: NSNotification.Name.UIKeyboardWillChangeFrame , object: nil)
}
override func viewDidDisappear(_ animated: Bool) {
NotificationCenter.default.removeObserver(self)
super.viewDidDisappear(animated)
}
func handleKeyboardNotification(notification: NSNotification) {
guard let userInfo = notification.userInfo,
let frameValue = userInfo[UIKeyboardFrameEndUserInfoKey] as? NSValue
else { return }
let duration:TimeInterval = (userInfo[UIKeyboardFrameEndUserInfoKey] as? NSNumber)?.doubleValue ?? 0
print(keyboardHeigthConstraint.constant)
UIView.animate(withDuration: duration, animations: {
//hardcoded 116 - it is buttonHeight + navBarHeight
self.keyboardHeigthConstraint.constant = UIScreen.main.bounds.height - frameValue.cgRectValue.size.height - 116
self.view.layoutIfNeeded()
})
print(keyboardHeigthConstraint.constant)
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.