관리 메뉴

김종권의 iOS 앱 개발 알아가기

[iOS - swift] navigationItem.searchController (검색바, 내비게이션바에 검색 창 추가 방법) 본문

iOS 응용 (swift)

[iOS - swift] navigationItem.searchController (검색바, 내비게이션바에 검색 창 추가 방법)

jake-kim 2021. 8. 26. 23:55

  • dataSource와 filterDataSource 따로 두고, 검색창이 활성화 된 상태 && 글자가 한글자라도 입력되면 filterDataSource 표출
  • filterDataSource는 UISearchResultsUpdating의 updateSearchResults(for:) 델리게이트에서 업데이트

구현 방법

  • viewController에 navigationController embed 상태
  • dataSource는 2벌 준비 (전체 dataSource, filterDataSource)
    var dataSource: [String] = ["iOS", "iOS 앱", "iOS 앱 개발", "iOS 앱 개발 알아가기", "iOS 앱 개발 알아가기 jake"]
    var filteredDataSource: [String] = []
  • navigationItem.searchController에 세팅
    private func setupSearchController() {

        let searchController = UISearchController(searchResultsController: nil)
        searchController.searchBar.placeholder = "검색(placeholder)"
        // 내비게이션 바는 항상 표출되도록 설정
        searchController.hidesNavigationBarDuringPresentation = false
        /// updateSearchResults(for:) 델리게이트를 사용을 위한 델리게이트 할당
        searchController.searchResultsUpdater = self
        /// 뒷배경이 흐려지지 않도록 설정
        searchController.obscuresBackgroundDuringPresentation = false

        navigationItem.searchController = searchController
        navigationItem.hidesSearchBarWhenScrolling = false
    }
  • 검색창 델리게이트인 UISearchResultsUpdating 준수
    • 위에서 searchController.searchResultsUpdater = self로 지정한것
      extension ViewController: UISearchResultsUpdating {
          func updateSearchResults(for searchController: UISearchController) {
              guard let text = searchController.searchBar.text else { return }
              filteredDataSource = dataSource.filter { $0.contains(text) }
              tableView.reloadData()
          }
      }
  • isEditMode 정의: edit모드일경우에만 filteredDataSource를 표출하도록 설계하기 위한 값
    var isEditMode: Bool {
        let searchController = navigationItem.searchController
        let isActive = searchController?.isActive ?? false
        let isSearchBarHasText = searchController?.searchBar.text?.isEmpty == false
        return isActive && isSearchBarHasText
    }
  • tableView delegate 준수
extension ViewController: UITableViewDelegate, UITableViewDataSource {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return isEditMode ? filteredDataSource.count : dataSource.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell")
        cell?.textLabel?.text = isEditMode ? filteredDataSource[indexPath.row] : dataSource[indexPath.row]
        return cell!
    }

    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return 70
    }

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        print(isEditing ? filteredDataSource[indexPath.row] : dataSource[indexPath.row])
    }
}

* 전체 소스코드: https://github.com/JK0369/SearchBarToNavigationItem

 

cf) return key를 누른 경우 delegate

searchController.searchBar.delegate = self

...

extension ViewController: UISearchBarDelegate {
    func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
		// TODO...
    }
}
Comments