• 키보드의 동작을 notification을 통해 감지하고, 그때 레이아웃 등의 변화를 적용
private func addKeyboardNotifications() {
NotificationCenter.default.addObserver(self,
selector: #selector(keyboardWillShow(_:)),
name: UIResponder.keyboardWillShowNotification,
object: nil)
NotificationCenter.default.addObserver(self,
selector: #selector(keyboardWillHide(_:)),
name: UIResponder.keyboardWillHideNotification,
object: nil)
}
private func removeKeyboardNotifications() {
NotificationCenter.default.removeObserver(self,
name: UIResponder.keyboardWillShowNotification,
object: nil)
NotificationCenter.default.removeObserver(self,
name: UIResponder.keyboardWillHideNotification,
object: nil)
}
addKeyboardNotifications() 에서
NotificationCenter addObserver 를 통해 키보드가 화면 위로 올라왔을때, 내려갈때를 감지할 수 있도록 등록해주었습니다.
removeKeyboardNotifications() 에서는 removeObserver 를 통해 해당 화면이 사라질때 메모리에서 해제해주어 메모리 누수를 방지해두었습니다.
@objc private func keyboardWillShow(_ notification: Notification) {
guard let userInfo = notification.userInfo,
let keyboardFrame = userInfo[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect,
let duration = userInfo[UIResponder.keyboardAnimationDurationUserInfoKey] as? TimeInterval else { return }
let keyboardHeight = keyboardFrame.height
self.customTextViewBottomConstraint?.update(offset: -3)
UIView.animate(withDuration: duration) {
self.view.transform = CGAffineTransform(translationX: 0, y: -keyboardHeight)
self.textView.movePlusButtonToBottom(true)
}
}
@objc private func keyboardWillHide(_ notification: Notification) {
guard let userInfo = notification.userInfo,
let duration = userInfo[UIResponder.keyboardAnimationDurationUserInfoKey] as? TimeInterval else { return }
self.customTextViewBottomConstraint?.update(offset: 0)
UIView.animate(withDuration: duration) {
self.view.transform = .identity
self.textView.movePlusButtonToBottom(false)
}
}
키보드가 올라오고 내려오는 동작을 감지할때 실행되는 함수들을 정의해 둔 곳입니다.
keyboardFrame.height를 통해 기기 자체의 keyboard 높이를 받아서 변수에 저장한 후, view의 y frame 값을 -(키보드 높이) 만큼 해주고 되돌려서 키보드 높이 위로 해당 화면이 올라갔다 내려갔다 하도록 레이아웃을 설정해 두었습니다.
private func setupDismissKeyboardGesture() {
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(dismissKeyboard))
tapGesture.cancelsTouchesInView = false
view.addGestureRecognizer(tapGesture)
}
@objc private func dismissKeyboard() {
view.endEditing(true)
}
이 함수를 통해, 키보드가 올라왔을때 다른 화면을 touch 하면 키보드가 내려갈 수 있도록 설정해두었습니다.
view.endEditing(true) 은 view 또는 그 하위 뷰 중 first responder가 있으면 이를 resign 시켜 키보드를 내리는 함수라고 합니다.