在显示键盘时,在iPad上的表单中调整tableview的大小

and*_*lin 6 objective-c uitableview ios

我在调整桌面视图时遇到困难,当键盘出现时滚动到活动文本字段,当视图以模态方式显示在iPad上的表单中时.它在iPhone上工作正常,因为我不必考虑表单视图的偏移量 - 我可以将tableview的底部contentInset更改为与键盘高度相同.但是,这不适用于iPad,因为表单及其表格视图不占用整个屏幕.

计算tableview的新底部contentInset应该是多少的最佳方法是什么?

Sim*_*ckx 12

好吧,我自己偶然发现了这个问题.我创建了一个适用于所有情况的解决方案(因此不仅仅是作为表单显示的viewControllers).解决方案是在Swift 3中,因此您仍然需要将其转换为Objective-C,但如果您仔细阅读注释,这应该不是问题.

解决方案的关键是在键盘动画完成时更新tableView(或scrollview)插图,并且表单位于其新位置.

在你的UIViewController子类中添加:

override func viewDidLoad() {
     super.viewDidLoad()
     NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillChangeFrame(_:)), name: .UIKeyboardWillChangeFrame, object: nil)
     NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillChangeFrame(_:)), name: .UIKeyboardWillHide, object: nil)
}
Run Code Online (Sandbox Code Playgroud)

这将添加一个观察者,以防键盘显示/隐藏.我们还需要取消订阅这些通知,否则应用会崩溃:

deinit {
    NotificationCenter.default.removeObserver(self)
}
Run Code Online (Sandbox Code Playgroud)

最后,最重要的代码:

func getTableViewInsets(keyboardHeight: CGFloat) -> UIEdgeInsets {
    // Calculate the offset of our tableView in the 
    // coordinate space of of our window
    let window = (UIApplication.shared.delegate as! AppDelegate).window!
    let tableViewFrame = tableView.superview!.convert(tableView.frame, to: window)

    // BottomInset = part of keyboard that is covering the tableView
    let bottomInset = keyboardHeight 
        - ( window.frame.height - tableViewFrame.height - tableViewFrame.origin.y )

    // Return the new insets + update this if you have custom insets
    return UIEdgeInsetsMake(
         tableView.contentInset.top, 
         tableView.contentInset.left, 
         bottomInset, 
         tableView.contentInset.right
    )
}

func keyboardWillChangeFrame(_ notification: Notification){
    guard let info = (notification as NSNotification).userInfo else {
        return
    }

    guard let animationDuration = info[UIKeyboardAnimationDurationUserInfoKey] as? TimeInterval else {
        return
    }

    // Default: keyboard will hide:
    var keyboardHeight: CGFloat = 0

    if notification.name == .UIKeyboardWillChangeFrame {
        // The keyboard will show
        guard let keyboardFrame = info[UIKeyboardFrameEndUserInfoKey] as? NSValue else {
            return
        }

        keyboardHeight = keyboardFrame.cgRectValue.height
    }

    let contentInsets = getTableViewInsets(keyboardHeight: keyboardHeight)

    UIView.animate(withDuration: animationDuration, animations: {
        self.tableView.contentInset = contentInsets
        self.tableView.scrollIndicatorInsets = contentInsets
    }, completion: {(completed: Bool) -> Void in
        // Chances are the position of our view has changed, (form sheet)
        // so we need to double check our insets
        let contentInsets = self.getTableViewInsets(keyboardHeight: keyboardHeight)
        self.tableView.contentInset = contentInsets
        self.tableView.scrollIndicatorInsets = contentInsets
    })
}
Run Code Online (Sandbox Code Playgroud)

  • 谢谢,对于 BottomInset 计算,我使用了 `let BottomInset = KeyboardHeight - (window.frame.maxY - tableViewFrame.maxY)` (2认同)