当MasterViewController处于搜索模式时,UISplitViewControllers DetailViewController有错误的contentInste.bottom

时间:2017-01-04 00:58:29

标签: ios uitableview layout keyboard uisearchbar

我在开发通用iOS应用时遇到了这个奇怪的问题。我的应用看起来很简单。在根目录,我有一个UITableViewController。第一个标签包含UISplitViewControllerUISplitViewController的主人是UINavigationControllerUITableViewController,详情为UINavigationControllerUITableViewController

此外,主表视图在tableHeaderView中有一个搜索栏,我用它来过滤条目。这一切都按预期工作但我看到一个问题出现在UISplitViewController同时显示主人和细节的设备上(例如iPad或大屏iPhone:

问题:当主人的搜索栏中的键盘处于活动状态时,详细信息的tableView错误contentInset.bottom

原因:我使用tableView.contentInset.toptableView.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>

See how the map is shifted up when the keyboard toolbar is enabled?

查看启用键盘工具栏后地图如何向上移动?这是因为在tableView(_:heightForRowAt:)tableView.contentInset.bottom是104而不是55。

Does not happen when the keyboard is not active

如果键盘未处于活动状态/搜索栏未聚焦,tableView.contentInset.bottom将返回49的正确高度。

1 个答案:

答案 0 :(得分:0)

<强>更新

原来,IQKeyboardManager中只有一个错误。在最近更新了库之后,一切都恢复正常并且按预期工作,即使没有自己处理任何键盘通知也是如此。

原始回答

我设法通过注册UIKeyboard通知并手动更改tableViews scrollViewInsetscontentInsets来解决此问题:

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)

}