Estenda a área segura do iOS 11 para incluir o teclado

O novo guia de layout da área segura, introduzido no iOS 11, funciona muito bem para impedir que o conteúdo seja exibido abaixo das barras, mas exclui o teclado. Isso significa que, quando um teclado é exibido, o conteúdo ainda está oculto por trás dele e esse é o problema que estou tentando resolver.

Minha abordagem é baseada em ouvir notificações do teclado e, em seguida, ajustar a área seguraadditionalSafeAreaInsets.

Aqui está o meu 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();
        }
    }
}

Isso funciona bem como oMyController é umUIViewController com umUITableView que se estende por toda a área segura. Agora, quando o teclado aparece, a parte inferior é levantada para que nenhuma célula fique atrás do teclado.

O problema está nas barras inferiores. Também tenho uma barra de ferramentas na parte inferior, que já está incluída na área segura. Portanto, definir a altura total do teclado como inserção adicional de área segura empurra demais a parte inferior da tabela exatamente pela altura da barra inferior. Para que este método funcione bem, devo definir oadditionalSafeAreaInsets.bottom ser igual à altura do teclado menos a altura da barra inferior.

Pergunta 1: Qual é a melhor maneira de reduzir a lacuna atual da área segura? Obter manualmente o quadro da barra de ferramentas e usar sua altura? Ou é possível obter a lacuna diretamente no guia de layout da área segura?

Pergunta 2: Presumivelmente, deve ser possível que a barra inferior mude de tamanho sem que o teclado mude de tamanho, por isso devo também implementar algum método para ouvir a alteração no quadro da barra. Isso é melhor feito emviewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator)? Ou em outro lugar?

Obrigado

questionAnswers(3)

yourAnswerToTheQuestion