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() } }
- 위에서 searchController.searchResultsUpdater = self로 지정한것
- 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...
}
}