iPhone X keyboard appear showing extra space
Try subtracting the height of the safe area's bottom inset when calculating the value for your constraint.
Here is a sample implementation which handles a UIKeyboardWillChangeFrame
notification.
@objc private func keyboardWillChange(_ notification: Notification) {
guard let userInfo = (notification as Notification).userInfo, let value = userInfo[UIKeyboardFrameEndUserInfoKey] as? NSValue else { return }
let newHeight: CGFloat
if #available(iOS 11.0, *) {
newHeight = value.cgRectValue.height - view.safeAreaInsets.bottom
} else {
newHeight = value.cgRectValue.height
}
myConstraint.value = newHeight
}
My issue was that my view was in a child view controller. Converting the CGRect did the trick.
@objc private func keyboardWillChangeFrame(notification: NSNotification) {
guard let userInfo = notification.userInfo, let endFrame = (userInfo[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue, let duration: TimeInterval = (userInfo[UIKeyboardAnimationDurationUserInfoKey] as? NSNumber)?.doubleValue else {
return
}
let convertedFrame = view.convert(endFrame, from: nil)
let endFrameY = endFrame.origin.y
let animationCurveRawNSN = userInfo[UIKeyboardAnimationCurveUserInfoKey] as? NSNumber
let animationCurveRaw = animationCurveRawNSN?.uintValue ?? UIViewAnimationOptions.curveEaseInOut.rawValue
let animationCurve: UIViewAnimationOptions = UIViewAnimationOptions(rawValue: animationCurveRaw)
if endFrameY >= UIScreen.main.bounds.size.height {
inputContainerViewBottomLayoutConstraint.constant = 0.0
} else {
var newHeight = view.bounds.size.height - convertedFrame.origin.y
if #available(iOS 11.0, *) {
newHeight = newHeight - view.safeAreaInsets.bottom
}
inputContainerViewBottomLayoutConstraint.constant = newHeight
}
UIView.animate(withDuration: duration, delay: TimeInterval(0), options: animationCurve, animations: {
self.view.layoutIfNeeded()
},completion: { _ in
self.scrollView.scrollToBottom()
})
}