我遇到一个问题,依靠convertRect
正确地报告要用于计算contentInset
的位置在iOS 12上不起作用。这种方法曾经在早期的iOS版本上起作用:< / p>
@objc func keyboardVisibilityChanged(notification: Notification) {
guard let userInfo = notification.userInfo else {
assertionFailure()
return
}
let keyboardScreenEndFrame = (userInfo[UIResponder.keyboardFrameEndUserInfoKey] as! NSValue).cgRectValue
let keyboardViewEndFrame = scrollView.convert(keyboardScreenEndFrame, from: view.window!)
if notification.name == UIResponder.keyboardWillHideNotification {
scrollView.contentInset = .zero
scrollView.scrollIndicatorInsets = .zero
} else {
let insets = UIEdgeInsets(top: 0, left: 0, bottom: (keyboardViewEndFrame.origin.y - keyboardViewEndFrame.size.height) , right: 0)
scrollView.contentInset = insets
scrollView.scrollIndicatorInsets = insets
}
}
但是,此代码虽然获得了非常接近的视觉效果,但并不精确,并且在iPhone(全屏显示模式)时也会中断。
答案 0 :(得分:0)
Apple states在其文档中:
注意:UIKeyboardFrameBeginUserInfoKey中包含的矩形 和userInfo的UIKeyboardFrameEndUserInfoKey属性 字典仅应用于其包含的尺寸信息。 请勿在以下位置使用矩形的原点(始终为{0.0,0.0}) 矩形相交操作。因为键盘是动画的 到位后,键盘的实际边界矩形会改变 随着时间的流逝。
所以我想出了以下解决方案,这些解决方案似乎可以在iOS 12和11上很好地工作:
// MARK: - Keyboard Notifications
@objc func keyboardVisibilityChanged(notification: Notification) {
if notification.name == UIResponder.keyboardWillHideNotification {
scrollView.contentInset = .zero
scrollView.scrollIndicatorInsets = .zero
}
else {
guard let userInfo = notification.userInfo,
let value = userInfo[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue,
let window = view.window else {
assertionFailure()
return
}
let keyboardScreenEndFrame = value.cgRectValue
let viewFrameInWindowCoordinates = window.convert(view.frame, from: view.superview)
let bottomEdgeOfViewInWindowBottomCoordinates = window.frame.maxY - viewFrameInWindowCoordinates.maxY
let contentInsetBottom = keyboardScreenEndFrame.height - bottomEdgeOfViewInWindowBottomCoordinates
let insets = UIEdgeInsets(top: 0, left: 0, bottom: contentInsetBottom, right: 0)
scrollView.contentInset = insets
scrollView.scrollIndicatorInsets = insets
}
}