기본 설정 및 UISearchController 구성
private let searchController = UISearchController(searchResultsController: nil)
func configureSearchController() {
searchController.searchResultsUpdater = self
searchController.obscuresBackgroundDuringPresentation = false
searchController.hidesNavigationBarDuringPresentation = false
searchController.searchBar.autocapitalizationType = .none
searchController.searchBar.autocorrectionType = .no
searchController.searchBar.spellCheckingType = .no
searchController.searchBar.placeholder = "Search"
navigationItem.searchController = searchController
definesPresentationContext = false
}
Swift
복사
•
searchResultsUpdater 프로퍼티를 현재 클래스(self)로 설정하여 사용자가 검색 바에 입력할 때마다 결과 업데이트
•
검색 중에 배경을 흐리게 하지 않음
•
내비게이션 바를 숨기지 않음
•
자동 대문자 비활성화
•
자동 수정 비활성화
•
맞춤법 검사 비활성화
검색 모드
private var inSearchMode: Bool {
return searchController.isActive && !searchController.searchBar.text!.isEmpty
}
Swift
복사
이 계산 속성은 사용자가 검색 중인지 아닌지를 파악하여 해당 상태에 따라 테이블 뷰에 표시될 데이터를 결정한다.
inSearchMode가 true일 때 사용자는 검색을 활성화하고 검색어를 한 글자 이상 입력한 상태이다. 이 경우, SearchController는 filteredUsers 배열을 사용하여 테이블 뷰를 채운다. 이 배열에는 사용자의 검색 조건에 부합하는 사용자 데이터만 포함되어 있다.
사용 이유
이 속성을 사용하는 이유는 사용자가 어떻게 데이터를 보고 싶어하는지, 즉 전체 목록을 보고 싶은지 아니면 특정 조건을 만족하는 항목만 보고 싶은지를 파악하기 위함이다. 이를 통해 앱은 사용자 경험을 개선하고 필요한 정보만을 효율적으로 제공할 수 있다.
isSearchMode를 활용한 동적 테이블 뷰 데이터 처리
extension SearchController {
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return inSearchMode ? filteredUsers.count : users.count
}
override func tableView(
_ tableView: UITableView,
cellForRowAt indexPath: IndexPath
) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(
withIdentifier: reuseIdentifier,
for: indexPath
) as! UserCell
let user = inSearchMode ? filteredUsers[indexPath.row] : users[indexPath.row]
cell.viewModel = UserCellViewModel(user: user)
return cell
}
}
Swift
복사
isSearchMode의 값에 따라 행의 수를 결정한다. 검색 모드가 활성화되면 filteredUsers 배얄의 크기를 반환하고 그렇지 않으면 users 배열의 크기를 반환한다.
테이블 뷰 델리게이트 메서드 활용
extension SearchController {
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let user = inSearchMode ? filteredUsers[indexPath.row] : users[indexPath.row]
let controller = ProfileController(user: user)
navigationController?.pushViewController(controller, animated: true)
}
}
Swift
복사
사용자가 테이블 뷰의 셀을 선택하면 isSearchMode 상태에 따라 적절한 사용자 데이터를 가져온다. 이 데이터는 선택된 사용자의 프로필을 보여주는 ProfileController로 전달된다.
검색 로직 및 필터링
func updateSearchResults(for searchController: UISearchController) {
guard let searchText = searchController.searchBar.text?.lowercased() else { return }
filteredUsers = users.filter({
$0.username.lowercased().contains(searchText) ||
$0.fullname.lowercased().contains(searchText)
})
tableView.reloadData()
}
Swift
복사
검색어가 입력될 때마다 updateSearchResults(for:) 메서드가 호출된다. 입력된 텍스트를 소문자로 변환한 후, username 또는 fullname에 검색어가 포함되는지 확인한다.
소문자로 변환하는 이유는 일관성을 유지하기 위함인데 사용자가 입력하는 텍스트는 대소문자를 혼용할 수 있기 때문이다. 예를 들어, 사용자가 ‘apple’, ‘Apple’, ‘APPLE’로 검색할 수 있다. 모든 입력을 소문자로 변환함으로써 데이터 소스의 해당 필드도 소문자로 변환하여 비교하여 일관된 검색 결과를 제공한다. 즉, 검색 정확도를 향상시킨다.
필터링된 사용자를 filteredUsers 배열에 저장하고 테이블 뷰에 변경사항을 반영한다.