Solution which worked for me
After struggling for days I finally manage to find the fix for view animation issue. For me keyboardWillChangeFrameNotification worked. The solution is discussed in the following thread:
Move textfield when keyboard appears swift
I've a bunch of views embedded inside stack view along with text view. I've given text view height of <= 120. In keyboardWillShow view doesn't animate despite adding code as required. I've played with duration value but it's all same result. I was wondering if it's due to text view? How to fix it?
@objc func keyboardWillShow(notification:NSNotification) {
    guard let keyboardValue = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue else { return }
    let keyboardScreenEndFrame = keyboardValue.cgRectValue
    let keyboardFrame = view.convert(keyboardScreenEndFrame, from: view.window)
    if #available(iOS 11.0, *) {
        scrollView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: keyboardFrame.height - view.safeAreaInsets.bottom, right: 0)
    } else {
        scrollView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: keyboardFrame.height, right: 0)
    }
    scrollView.scrollIndicatorInsets = scrollView.contentInset
    let bottomOffset = CGPoint(x: 0, y: scrollView.contentSize.height + keyboardFrame.height - scrollView.bounds.size.height)
    scrollView.setContentOffset(bottomOffset, animated: true)
    UIView.animate(withDuration: 0.5, animations: { () -> Void in
        self.view.layoutIfNeeded()
    })
}
===
   extension FirstViewController: UITextViewDelegate {
    func textViewDidChange(_ textView: UITextView) {
        let estimatedSize = textView.sizeThatFits(textView.frame.size)
        if estimatedSize.height > textViewMaxHeight {
            if estimatedSize.height - textViewMaxHeight < textView.font!.lineHeight && !didExpandTextView {
                didExpandTextView = true
                var contentInset:UIEdgeInsets = UIEdgeInsets(top: 0.0, left: 0.0, bottom: self.savedKbHeight, right: 0.0)
                if let v = self.tabBarController?.tabBar {
                    contentInset.bottom -= v.frame.height
                }
                scrollView.contentInset = contentInset
                scrollView.scrollIndicatorInsets = contentInset
                if textView.isFirstResponder {
                    let fr = textView.frame
                    scrollView.scrollRectToVisible(fr, animated: false)
                }
            }
            textView.isScrollEnabled = true
            textView.showsVerticalScrollIndicator = true
        } else {
            if let lineHeight = textView.font?.lineHeight, Int(estimatedSize.height / lineHeight) != numberOfLines {
                numberOfLines = Int(estimatedSize.height / textView.font!.lineHeight)
                var contentInset:UIEdgeInsets = UIEdgeInsets(top: 0.0, left: 0.0, bottom: self.savedKbHeight, right: 0.0)
                print("contentInset: \(contentInset)")
                scrollView.contentInset = contentInset
                scrollView.scrollIndicatorInsets = contentInset
                if textView.isFirstResponder {
                    let fr = textView.frame
                    scrollView.scrollRectToVisible(fr, animated: false)
                }
                didExpandTextView = false
            }
            textView.isScrollEnabled = false
        }
    }
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
    textField.resignFirstResponder()
    return true
}

 
    