Extienda el Área segura de iOS 11 para incluir el teclado

La nueva guía de diseño de Área segura introducida en iOS 11 funciona muy bien para evitar que el contenido se muestre debajo de las barras, pero excluye el teclado. Eso significa que cuando se muestra un teclado, el contenido sigue oculto detrás de él y este es el problema que estoy tratando de resolver.

Mi enfoque se basa en escuchar las notificaciones del teclado y luego ajustar el área segura a través deadditionalSafeAreaInsets.

Aquí está mi código:

override func viewDidLoad() {
    let notificationCenter = NotificationCenter.default
    notificationCenter.addObserver(self, selector: #selector(keyboardWillShow(notification:)), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
    notificationCenter.addObserver(self, selector: #selector(keyboardWillHide(notification:)), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
    notificationCenter.addObserver(self, selector: #selector(keyboardWillChange(notification:)), name: NSNotification.Name.UIKeyboardWillChangeFrame, object: nil)
}

//MARK: - Keyboard
extension MyViewController {
    @objc func keyboardWillShow(notification: NSNotification) {
        let userInfo = notification.userInfo!
        let keyboardHeight = (userInfo[UIKeyboardFrameEndUserInfoKey] as! NSValue).cgRectValue.height

        additionalSafeAreaInsets = UIEdgeInsets(top: 0, left: 0, bottom: keyboardHeight, right: 0)
        UIView.animate(withDuration: 0.3) {
            self.view.layoutIfNeeded();
        }
    }

    @objc func keyboardWillHide(notification: NSNotification) {
        additionalSafeAreaInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
        UIView.animate(withDuration: 0.3) {
            self.view.layoutIfNeeded();
        }
    }

    @objc func keyboardWillChange(notification: NSNotification) {
        let userInfo = notification.userInfo!
        let keyboardHeight = (userInfo[UIKeyboardFrameEndUserInfoKey] as! NSValue).cgRectValue.height

        additionalSafeAreaInsets = UIEdgeInsets(top: 0, left: 0, bottom: keyboardHeight, right: 0)

        UIView.animate(withDuration: 0.3) {
            self.view.layoutIfNeeded();
        }
    }
}

Esto funciona bien ya queMyController es unUIViewController con unUITableView que se extiende por toda el área segura. Ahora, cuando aparece el teclado, la parte inferior se empuja hacia arriba para que no haya celdas detrás del teclado.

El problema es con las barras inferiores. También tengo una barra de herramientas en la parte inferior que ya está incluida en el área segura. Por lo tanto, establecer la altura completa del teclado como inserción de área segura adicional empuja demasiado la parte inferior de la vista de la tabla exactamente por la altura de la barra inferior. Para que este método funcione bien, debo configurar eladditionalSafeAreaInsets.bottom ser igual a la altura del teclado menos la altura de la barra inferior.

Pregunta 1: ¿Cuál es la mejor manera de obtener la brecha de área segura actual en el fondo? ¿Obtener manualmente el marco de la barra de herramientas y usar su altura? ¿O es posible obtener la brecha directamente de la guía de diseño del área segura?

Pregunta 2: Presumiblemente debería ser posible que la barra inferior cambie de tamaño sin que el teclado cambie de tamaño, por lo que también debería implementar algún método para escuchar el cambio en el marco de la barra. ¿Se hace esto mejor enviewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator)? O en otro lado?

Gracias

Respuestas a la pregunta(3)

Su respuesta a la pregunta