Resize tableview in form sheet on iPad when keyboard is shown

Okay, I stumbled on this issue myself. I created a solution that works in every situation (so not only for viewControllers presented as a form sheet). Solution is in Swift 3, so you still need to convert it to Objective-C, but that shouldn't be a problem if your read the comments carefully.

The key of the solution is to update the tableView (or scrollview) insets when the keyboard animation is finished, and the form sheet is on it's new position.

In your UIViewController subclass add:

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)
}

This will add an observer in case the keyboard will show / hide. We also need to unsubscribe from these notifications, or the app will crash:

deinit {
    NotificationCenter.default.removeObserver(self)
}

And finally, the most important code:

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
    })
}