‼️ 2023.07 추가
여러분분분,, 혹시 최소 타겟이 iOS 15라면 제발 keyboardlayoutGuide 를 사용하십시다 진짜 좋아요
최소 타겟이 15보다 낮으시다면.....화이팅 😅
위와 같이 댓글을 작성할 때 뷰 하단의 댓글 입력 창 (textField)를 가지는 댓글입력View가 키보드 위로 올라오는 화면 구현하기
따라서 ScrollView를 조정하여 더 자연스러운 UI를 제공하려고 한다.
💡 ScrollView 내부를 StackView로 구성한 이유?
: ScrollView 내부를 UIView로 구성하게 되면, 해당 UIView의 높이가 고정되지 않는 경우 스크롤이 되지 않는 이슈가 발생하기에 stackView를 사용하여 높이 고정 이슈 해결할 수 있다.
keyboard가 활성화되었을 때 scrollView를 위로 올리고, 비활성화되었을 때 scrollView를 아래로 내려야한다.
그러나 그 시점을 계산할 수 없기 때문에 이를 알려주는 observer가 필요한데
💡 UIKit은 UIResponder.keyboardWillShowNotification, UIResponder.keyboardWillHideNotification 를 내장하고 있다
따라서 NotificationCenter에 위 observer들을 추가해주기만 하면 된다
func addKeyboardObserver() {
NotificationCenter.default.addObserver(self,
selector: #selector(keyboardWillShow(_:)),
name: UIResponder.keyboardWillShowNotification,
object: nil)
NotificationCenter.default.addObserver(self,
selector: #selector(keyboardWillHide(_:)),
name: UIResponder.keyboardWillHideNotification,
object: nil)
}
따라서 이제 각 함수에 Keyboard의 높이만큼 ScrollView의 높이를 올리거나, 내리를 코드를 작성하면 된다
@objc private func keyboardWillShow(_ notification: Notification) {
guard let userInfo = notification.userInfo as NSDictionary?,
let keyboardFrame = (userInfo[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue else {
return
}
/// 키보드의 높이
let keyboardHeight = keyboardFrame.size.height
/// 댓글 입력(textField)를 포함하고 있는 View
let commentViewHeight = 61.0
commentViewBottomConstraint.constant = keyboardHeight - self.view.safeAreaInsets.bottom
scrollView.contentOffset.y = keyboardHeight + commentViewHeight
UIView.animate(withDuration: 0.3,
animations: { self.view.layoutIfNeeded()},
completion: nil)
}
@objc private func keyboardWillHide(_ notification: NSNotification) {
scrollView.contentOffset.y = .zero
scrollView.scrollIndicatorInsets = self.scrollView.contentInset
commentViewBottomConstraint.constant = .zero
UIView.animate(withDuration: 0.3,
animations: { self.view.layoutIfNeeded()},
completion: nil)
}
키보드가 비활성화 되는 경우 댓글 입력 창과 scrollView 둘 다 view의 bottom으로 내려와야한다. 따라서 .zero 값을 넣어주면 된다
func removeKeyBoardObserver() {
NotificationCenter.default.removeObserver(UIResponder.keyboardWillShowNotification)
NotificationCenter.default.removeObserver(UIResponder.keyboardWillHideNotification)
}
마지막으로, 이 viewController를 벗어나면 이 observer들은 더이상 필요가 없기 때문에 viewWillDisappear에서 이 removeKeyBoardObserver()를 호출하여 observer를 제거한다.