I am trying to get a UIView to move up in sync with my keyboard when it is opened so the typing field remains in the display when the keyboard is up. However, while it does seem like the frame of the view is being updated in the code, the animation doesn't show in the simulator. The code is show below. I am working in XCode 12 and doing this fully programatically (no storyboards). This function activates whenever the notification for the keyboard opening is posted. The output of this is as follows:
showing keyboard
begin
(0.0, 528.96, 375.0, 88.16)
end
(0.0, 528.96, 375.0, 88.16)
this should be changed
(0.0, 237.96000000000004, 375.0, 379.15999999999997)
end
(0.0, 237.96000000000004, 375.0, 379.15999999999997)
@objc private func keyboardWillShow(notification: NSNotification) {
print("showing keyboard")
let userInfo: NSDictionary = notification.userInfo! as NSDictionary
let keyboardFrame: NSValue = userInfo.value(forKey: UIResponder.keyboardFrameEndUserInfoKey) as! NSValue
let keyboardRectangle = keyboardFrame.cgRectValue
let keyboardHeight = keyboardRectangle.height
let commentViewSize: CGFloat = view.height/7
print("begin")
print(commentFieldView.frame)
UIView.animate(withDuration: 0.1, delay: 0, animations: { [weak self] in
guard let strongSelf = self else {
return
}
DispatchQueue.main.async {
strongSelf.commentFieldView.frame = CGRect(x: 0, y: strongSelf.view.height - commentViewSize - keyboardHeight, width: strongSelf.view.width, height: commentViewSize + keyboardHeight)
strongSelf.profilePic.frame = CGRect(x: strongSelf.commentFieldView.left + 15, y: strongSelf.commentFieldView.height/5, width: 100, height: 100)
print("this should be changed")
print(strongSelf.commentFieldView.frame)
}
}) { _ in
print("end")
print(self.commentFieldView.frame)
}
print("end")
print(self.commentFieldView.frame)
}
The problem is the use of
DispatchQueue.main.asyncinsideUIView.animate. That prevents that code from being animated. The keyboard notification will only be called on the main queue and the code insideanimationblock will be called on the same queue that you callUIView.animateon.