我在开发通用iOS应用时遇到了这个奇怪的问题。我的应用看起来很简单。在根目录,我有一个UITableViewController
。第一个标签包含UISplitViewController
。 UISplitViewController
的主人是UINavigationController
,UITableViewController
,详情为UINavigationController
,UITableViewController
。
此外,主表视图在tableHeaderView
中有一个搜索栏,我用它来过滤条目。这一切都按预期工作但我看到一个问题出现在UISplitViewController
同时显示主人和细节的设备上(例如iPad或大屏iPhone:
问题:当主人的搜索栏中的键盘处于活动状态时,详细信息的tableView
错误contentInset.bottom
。
原因:我使用tableView.contentInset.top
和tableView.contentInset.bottom
以及tableView.bounds.height
来计算tableView(_:heightForRowAt:)
中的地图单元格高度,具体取决于有多少其他单元格我显示。
我对其进行了调试,通常情况下,.top
插入为64,.bottom
为49,这是状态栏+导航栏和标签栏的预期值。但是,当键盘在搜索栏中处于活动状态时,.bottom
插图变为104,这是标签栏 PLUS 键盘工具栏55的49。正如您所看到的,键盘工具栏覆盖了tabbar并且不仅仅是将其向上移动,我认为tableview错误地计算了它的.bottom
插入。
问题我必须做什么,以便在没有标签栏时tableView.contentInset.bottom
为0,如果有标签栏则为49,如果有一个工具栏覆盖标签栏,则为55? / p>
查看启用键盘工具栏后地图如何向上移动?这是因为在tableView(_:heightForRowAt:)
中tableView.contentInset.bottom
是104而不是55。
如果键盘未处于活动状态/搜索栏未聚焦,tableView.contentInset.bottom
将返回49的正确高度。
答案 0 :(得分:0)
<强>更新强>
原来,IQKeyboardManager中只有一个错误。在最近更新了库之后,一切都恢复正常并且按预期工作,即使没有自己处理任何键盘通知也是如此。
原始回答
我设法通过注册UIKeyboard通知并手动更改tableViews scrollViewInsets
和contentInsets
来解决此问题:
func viewDidLoad(){
...
let center = NotificationCenter.default
center.addObserver(self, selector: #selector(keyboardWillShow(_:)), name: .UIKeyboardWillShow, object: nil)
center.addObserver(self, selector: #selector(keyboardWillHide(_:)), name: .UIKeyboardWillHide, object: nil)
}
func keyboardWillShow(_ notification: Notification) {
guard let userInfo = notification.userInfo else { return }
guard let endFrame = (userInfo[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue else { return }
let duration:TimeInterval = (userInfo[UIKeyboardAnimationDurationUserInfoKey] as? NSNumber)?.doubleValue ?? 0
let animationCurveRawNSN = userInfo[UIKeyboardAnimationCurveUserInfoKey] as? NSNumber
let animationCurveRaw = animationCurveRawNSN?.uintValue ?? UIViewAnimationOptions.curveEaseInOut.rawValue
let animationCurve:UIViewAnimationOptions = UIViewAnimationOptions(rawValue: animationCurveRaw)
self.keyboardHeight = endFrame.size.height
self.tableView.contentInset.bottom = endFrame.size.height
self.tableView.scrollIndicatorInsets.bottom = endFrame.size.height
let animations: () -> Void = {
self.tableView.beginUpdates()
self.tableView.endUpdates()
self.view.layoutIfNeeded()
}
UIView.animate(withDuration: duration,
delay: TimeInterval(0),
options: animationCurve,
animations: animations,
completion: nil)
}
func keyboardWillHide(_ notification: Notification) {
guard let userInfo = notification.userInfo else { return }
let duration:TimeInterval = (userInfo[UIKeyboardAnimationDurationUserInfoKey] as? NSNumber)?.doubleValue ?? 0
let animationCurveRawNSN = userInfo[UIKeyboardAnimationCurveUserInfoKey] as? NSNumber
let animationCurveRaw = animationCurveRawNSN?.uintValue ?? UIViewAnimationOptions.curveEaseInOut.rawValue
let animationCurve:UIViewAnimationOptions = UIViewAnimationOptions(rawValue: animationCurveRaw)
self.keyboardHeight = 0.0
self.tableView.contentInset.bottom = 49.0
self.tableView.scrollIndicatorInsets.bottom = 49.0
let animations: () -> Void = {
self.tableView.beginUpdates()
self.tableView.endUpdates()
self.view.layoutIfNeeded()
}
UIView.animate(withDuration: duration,
delay: TimeInterval(0),
options: animationCurve,
animations: animations,
completion: nil)
}