# 서치바 구현
서치바는 UISearchController
인스턴스를 생성하여 활용한다.
let searchController = UISearchController()
func setupSearchBar(){
self.title = "Music Search"
navigationItem.searchController = searchController
searchController.searchBar.delegate = self
searchController.searchBar.autocapitalizationType = .none
}
일반적으로 검색기능을 사용하면 검색 결과에 대해 push되는 형태로 화면이 관리되기 때문에 네비게이션 컨트롤러를 사용하게 된다.
뷰컨트롤러 내에서 navigationItem
속성에 접근하게 되면 searchController
라는 내부 속성에 다시 접근이 가능하다. 이 속성에 위에서 생성한 UISearchController
인스턴스를 할당하면 된다.
navigationItem
... Therefore, you should not access this property if you are not using a navigation controller to display the view controller. .. [swift document navigationItem - Discussion]
navigationItem 속성은 네비게이션 컨트롤러 기반의 뷰 컨트롤러 위에서만 접근 가능하다.
서치바는 navigationItem.searchController
속성의 인스턴스로 연결하는 것 외에 델리게이트 패턴이 동일하게 사용된다. 텍스트필드 델리게이트 패턴과 유사하게, 서치바 입력 및 키보드 제어에 대한 동작 책임을 뷰컨트롤러에게 위임하게 된다.
UISearchBarDelegate
프로토콜을 채택하여 내부 메서드를 구현하면 되며 필수 메서드는 없다.
extension ViewController: UISearchBarDelegate{
// 키보드가 입력될때마다 요청을 보내서 매번 화면을 새로 그리는 로직
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
self.musicArrays = []
networkManager.fetchMusic(searchTerm: searchText) { result in
switch result {
case .success(let musicData):
self.musicArrays = musicData
DispatchQueue.main.async {
self.musicTableView.reloadData()
}
case .failure(let error):
print(error.localizedDescription)
}
}
}
// 키보드의 Search 버튼을 클릭했을때만 네트워크 요청을 시작하는 로직
func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
guard let text = searchController.searchBar.text else {
return
}
print(text)
self.musicArrays = []
networkManager.fetchMusic(searchTerm: text) { result in
switch result{
case .success(let musicData):
self.musicArrays = musicData
DispatchQueue.main.async {
self.musicTableView.reloadData()
}
case .failure(let error):
print(error.localizedDescription)
}
}
self.view.endEditing(true)
}
}
# SearchResult
검색을 하고 그 결과로서 나타나는 UIView를