-
[iOS] RxSwift를 이용하여 키보드 컨트롤하기 (NotificationCenter)스위프트 2023. 8. 22. 14:28
Overview
앱 개발을 하면 키보드에 따른 UI 변경을 해야 하는 상황을 마주합니다.
전에 RxKeyBoard라는 라이브러리 사용법을 소개한 적이 있습니다. (https://hogumachu.tistory.com/14)
이번에는 RxSwift만을 사용해서 컨트롤해 봅시다.
RxSwift 없이 사용하는 방법
@objc private func keyboardWillShow(notification: NSNotification) { guard let keyboardSize = (notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue else { return } print(keyboardSize) }
일단 notification을 통해 키보드의 크기를 받는 메서드를 만듭니다. (굉장히 깁니다)
private func setupKeyboard() { NotificationCenter.default.addObserver( self, selector: #selector(keyboardWillShow(notification:)), name: UIResponder.keyboardWillShowNotification, object: nil ) }
다음으로 키보드 등장에 대한 Observer를 등록해 주면 끝입니다.
private func setupKeyboard() { NotificationCenter.default.addObserver( self, selector: #selector(keyboardWillShow(notification:)), name: UIResponder.keyboardWillShowNotification, object: nil ) NotificationCenter.default.addObserver( self, selector: #selector(keyboardWillHide(notification:)), name: UIResponder.keyboardWillHideNotification, object: nil ) }
만약 키보드가 사라지는 이벤트도 받고 싶다면 위처럼 등록하면 됩니다.
생각보다 간단합니다.
RxSwift를 사용하여 키보드 높이 확인하기
import RxSwift extension Reactive where Base: NotificationCenter { var keyboardWillShow: Observable<Notification> { return base.rx.notification(UIResponder.keyboardWillShowNotification) } var keyboardWillHide: Observable<Notification> { return base.rx.notification(UIResponder.keyboardWillHideNotification) } }
먼저 keyboard에 대한 Notification을 설정합니다.
NotificationCenter.default.rx.keyboardWillShow NotificationCenter.default.rx.keyboardWillHide
설정을 하면 위처럼 바로 키보드 이벤트에 대한 스트림을 구독할 수 있게 됩니다.
extension Notification { var keyboardSize: CGRect? { return (userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue } }
키보드 사이즈 값을 가져오는 것도 꽤나 긴 것 같으니 Extension을 통해 만들어 줍니다.
NotificationCenter.default.rx.keyboardWillShow .compactMap { $0.keyboardSize }
위처럼 바로 키보드의 사이즈를 얻을 수 있습니다.
private func setupKeyboard() { NotificationCenter.default.rx.keyboardWillShow .compactMap { $0.keyboardSize } .bind(to: keyboardShowBinder) .disposed(by: disposeBag) NotificationCenter.default.rx.keyboardWillHide .bind(to: keyboardHideBinder) .disposed(by: disposeBag) } private var keyboardShowBinder: Binder<CGRect> { return Binder(self) { this, keyboardSize in this.buttonBottomConstraint?.update(offset: -keyboardSize.height) UIView.animate(withDuration: 0.3) { this.view.layoutIfNeeded() } } } private var keyboardHideBinder: Binder<Notification> { return Binder(self) { this, _ in this.buttonBottomConstraint?.update(offset: -10) UIView.animate(withDuration: 0.3) { this.view.layoutIfNeeded() } } }
키보드에 대한 동작을 따로 Binder로 만들면 코드가 제법 깔끔해집니다.
'스위프트' 카테고리의 다른 글
[iOS] 모듈화를 해야 하는 이유 (0) 2024.01.14 [iOS] ViewController Life Cycle (+ ViewIsAppearing) (0) 2023.09.02 [Swift] 티스토리 블로그를 자동으로 Github에 업데이트 (Git Actions) (6) 2023.08.07 [iOS] Life Cycle (App, Scene 생명 주기) (0) 2023.07.30 [iOS] UITextField를 RxDelegateProxy를 이용하여 사용해보자 (0) 2023.07.29