P.S.
제가 작성한 내용도 괜찮지만 유지보수 측면에서 프로덕션 환경이라면 IQKeyboardManager 라이브러리 사용을 권장드립니다 🙂
protocol KeyboardEvader where Self: UIViewController {
var keyboardScrollView: UIScrollView { get }
func registerForKeyboardNotification()
}
extension KeyboardEvader where Self: UIViewController {
func registerForKeyboardNotification() {
NotificationCenter.default.addObserver(
forName: UIResponder.keyboardWillShowNotification,
object: nil,
queue: OperationQueue.main
) { [weak self] notification in
self?.keyboardWillShow(notification: notification)
}
NotificationCenter.default.addObserver(
forName: UIResponder.keyboardWillHideNotification,
object: nil,
queue: OperationQueue.main
) { [weak self] notification in
self?.keyboardWillHide(notification: notification)
}
}
private func keyboardWillShow(notification: Notification) {
guard let keyboardFrame = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect else {
assertionFailure("Couldn't get keyboard frame.")
return
}
let insets = UIEdgeInsets(top: 0, left: 0, bottom: keyboardFrame.height, right: 0)
keyboardScrollView.contentInset = insets
keyboardScrollView.scrollIndicatorInsets = insets
}
private func keyboardWillHide(notification: Notification) {
keyboardScrollView.contentInset = .zero
keyboardScrollView.scrollIndicatorInsets = .zero
}
}
해당 코드를 KeyboardEvader.swift
로 생성. 그 후 ViewController
에서 상속받도록하고 registerForKeyboardNotification
함수 호출할 수 있도록 설정.
final class ViewController: UIViewController, KeyboardEvader {
var keyboardScrollView: UIScrollView { return mainScrollView }
override func viewDidLoad() {
super.viewDidLoad()
registerForKeyboardNotification()
}
}
Extension
이 아닌 Protocol
를 사용한 이유?
- 많은 ViewController에서 해당 함수가 자동 완성 되는 것 조차 싫었음.
- 키보드가 나오지 않는 화면에서는 해당 함수를 사용할 필요가 없기 때문에…