본문 바로가기
🍎 Swift/iOS 학습 노트

[Swift🍎] UISearchController 키보드 숨김처리

by 솔비님 2024. 9. 26.

UISearchController로 네비게이션바에 서치바 생성 후 테이블뷰에 데이터를 받아오는 상황!!

서치바가 활성화 된 상태에서 테이블뷰를 스크롤했을 때 키보드가 내려가지 않는다

 

 

탭 제스처 인식기도 써보고 여러가지를 해봤는데,

일단 텍스트뷰가 없는 상황에서는 탭 제스터 인식기는 적절하지 못하다고 함(실제로 동작 안함)

 

테이블뷰 Delegate를 사용하는 방법도 있는데, 딜리게이트는 복잡하기도 하고 코드가 길어져서 선호하지 않는 편이다..

 

그래서 RxSwift와 endEditing을 이용해서 처리해 보기로 했다

        gymTableView.rx.willBeginDragging
            .subscribe(onNext: { [weak self] _ in
                self?.view.endEditing(true)
            })
            .disposed(by: disposeBag)
    }

 

 

음.. 안됨 ㅎㅎㅎㅎ

 

또 여기저기 찾아보다가 알아낸 사실인데

view.endEditing(true) 메서드는 호출된 뷰랑 그 하위 모든 뷰에서 편집 중인 모든 텍스트필드&뷰를 종료한다고 시도한다고 한다

하지만, 내가 사용한 UISearchController는 내부적으로 키보드의 상태를 제어하기 때문에 해당 메서드가 먹히지 않는다는 것!

 

    func setupKeyboardDismissOnScroll() {
        gymTableView.rx.willBeginDragging
            .subscribe(onNext: { [weak self] _ in
                if self?.searchController.isActive ?? false {
                    self?.searchController.isActive = false  //검색 컨트롤러 비활성화
                } else {
                    self?.view.endEditing(true)
                }
            })
            .disposed(by: disposeBag)
     }

UISearchControllerisActive 속성을 false로 설정하면 검색 컨트롤러가 비활성화되고 키보드가 숨겨진다!

다만 검색한 내용이 완전히 지워져버려 스크롤 시 테이블뷰의 최상단으로 올라가 버린다는 것인데..

 

그래서 다시 또 검색 ㅠㅠ

 

searchController.searchBar의 resignFirstResponder() 를 사용하면 된다는 정보 발견

해당 메서드는 필드에서 첫 번째 응답자(first responder) 상태를 포기하게 하고, 이 경우에는 키보드가 숨겨지고 검색상태(스크롤 위치)가 유지된다고 한다

 

func setupKeyboardDismissOnScroll() {
    gymTableView.rx.willBeginDragging
        .subscribe(onNext: { [weak self] _ in
            // 키보드가 활성화된 상태에서만 키보드를 숨김
            if self?.searchController.searchBar.isFirstResponder == true {
                self?.searchController.searchBar.resignFirstResponder()
            }
        })
        .disposed(by: disposeBag)

 

 

성공! 어우 힘들다