             UIView.animate(
                 withDuration: duration,
                 animations: { self.view.layoutIfNeeded() },
-                completion: { (_) in callback?() }
+                completion: { _ in }
             )
+            CATransaction.setCompletionBlock(callback) // this callback is guaranteed to be called
             CATransaction.commit()
             self.isAdjustingInputContainer = false
         } else {

                initialSpringVelocity: initialSpringVelocity,
                options: .curveLinear,
                animations: { self.view.layoutIfNeeded() },
                completion: { (_) in callback?() })
            self.isAdjustingInputContainer = false
        } else {
            self.changeInputContentBottomMarginWithoutAnimationTo(newValue, callback: callback)

        if animated {
            self.isAdjustingInputContainer = true
            self.inputContainerBottomConstraint.constant = max(newValue, self.bottomLayoutGuide.length)
            CATransaction.begin()
            UIView.animate(
                withDuration: duration,
                delay: 0.0,
