ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [iOS] RxSwift를 이용하여 키보드 컨트롤하기 (NotificationCenter)
    스위프트 2023. 8. 22. 14:28

    Overview


    앱 개발을 하면 키보드에 따른 UI 변경을 해야 하는 상황을 마주합니다.

    전에 RxKeyBoard라는 라이브러리 사용법을 소개한 적이 있습니다. (https://hogumachu.tistory.com/14)

    이번에는 RxSwift만을 사용해서 컨트롤해 봅시다.

     

    키보드 show/hide 예시 영상

     

    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로 만들면 코드가 제법 깔끔해집니다.

Designed by Tistory.