Project/CafePoCa
🔍 SearchController를 통해 검색 기능 구현하기
밤새는 탐험가89
2025. 6. 10. 18:31
🔍 구현하려는 상황
- homeHeaderView에 위치한 searchTextField로부터 입력받은 텍스트를 통해 검색
✅ searchTextField에서 입력받은 텍스트를 KeywordSearchViewController에 델리게이트 패턴으로 전달
class HomeHeaderView: UIView {
// MARK: - Variable
weak var delegate: HomeHeaderViewDelegate?
...
}
extension HomeHeaderView {
private func setupGesture() {
...
searchButton.addTarget(self, action: #selector(didTappedSEarchButton), for: .touchUpInside)
}
...
@objc private func didTappedSEarchButton() {
let keyword = searchTextField.text ?? ""
delegate?.didTappedSearchButton(with: keyword)
}
}
protocol HomeHeaderViewDelegate: AnyObject {
...
func didTappedSearchButton(with keyword: String)
}
✅ HomeViewController에서 델리게이트 패턴에 따른 함수 구체화
extension HomeViewController: HomeHeaderViewDelegate {
...
func didTappedSearchButton(with keyword: String) {
print("✅ 현재 눌린 검색어: \(keyword)")
UIView.animate(withDuration: 0.25) {
self.view.endEditing(true)
}
let vc = KeywordSearchViewController(with: keyword)
navigationController?.pushViewController(vc, animated: true)
}
}
✅ UISearchController를 담고 있는 KeywordSearchViewController 설계
import UIKit
class KeywordSearchViewController: UIViewController {
// MARK: - Variable
private var keyword: String = ""
private var shouldActivateSearch: Bool = true
// MARK: - UI Component
private lazy var searchController: UISearchController = {
let controller = UISearchController(searchResultsController: resultsViewController)
controller.searchResultsUpdater = self
controller.obscuresBackgroundDuringPresentation = false
controller.searchBar.placeholder = "Search"
return controller
}()
private let resultsViewController = KeywordResultsViewController()
// MARK: - Init
init(with keyword: String) {
super.init(nibName: nil, bundle: nil)
self.keyword = keyword
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
// MARK: - Life Cycle
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .systemBackground
searchControllerSetup()
setupNavigationBar()
searchController.searchBar.text = keyword
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
if shouldActivateSearch {
shouldActivateSearch = false // 한 번만 실행되도록 방지
searchController.isActive = true
DispatchQueue.main.asyncAfter(deadline: .now() + 0.05) {
self.searchController.searchBar.becomeFirstResponder()
self.resultsViewController.updateResults(for: self.keyword)
}
}
}
// MARK: - Function
private func searchControllerSetup() {
navigationItem.searchController = searchController
definesPresentationContext = true
}
}
// MARK: - Extension: UISearchResultsUpdating
extension KeywordSearchViewController: UISearchResultsUpdating {
func updateSearchResults(for searchController: UISearchController) {
guard let query = searchController.searchBar.text,
!query.isEmpty,
let resultsVC = searchController.searchResultsController as? KeywordResultsViewController else {
return
}
resultsVC.updateResults(for: query)
}
}
// MARK: - Extension: NavigaitonBar Setup
extension KeywordSearchViewController {
private func setupNavigationBar() {
navigationItem.backBarButtonItem?.isHidden = true
let config = UIImage.SymbolConfiguration(pointSize: 20)
let backButtonImage = UIImage(systemName: "arrow.backward.square", withConfiguration: config)
let backButton = UIBarButtonItem(image: backButtonImage, style: .plain, target: self, action: #selector(backButtonTapped))
backButton.tintColor = .label
self.navigationItem.leftBarButtonItem = backButton
navigationItem.title = "Search"
}
@objc private func backButtonTapped() {
navigationController?.popViewController(animated: true)
}
}
🔥 검색창에 검색어를 입력하고 난 후에 검색버튼을 누르면 바로 검색 결과가 보이게 하기 위해서 아래 코드 추가
아래 코드 없이는, 검색버튼을 누르면 검색결과가 바로 보이지 않음
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .systemBackground
searchControllerSetup()
setupNavigationBar()
searchController.searchBar.text = keyword
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
if shouldActivateSearch {
shouldActivateSearch = false // 한 번만 실행되도록 방지
searchController.isActive = true
DispatchQueue.main.asyncAfter(deadline: .now() + 0.05) {
self.searchController.searchBar.becomeFirstResponder()
self.resultsViewController.updateResults(for: self.keyword)
}
}
}
✅ 검색결과를 보여줄 KeywordResultsViewController 구현
- 간단한 더미데이터를 통해 기능 확인
- 검색결과는 간단히 테이블뷰로 보여줌
class KeywordResultsViewController: UIViewController {
// MARK: - Variable
private var dummyData: [String] = ["스타벅스", "메가커피", "컴포즈커피", "카페베네", "할리스커피"]
private var results: [String] = []
// MARK: - UI Component
private var tableView: UITableView = UITableView()
// MARK: - Life Cycle
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .systemBackground
tableViewSetup()
}
// MARK: - Function
private func tableViewSetup() {
view.addSubview(tableView)
tableView.frame = view.bounds
tableView.showsVerticalScrollIndicator = false
tableView.dataSource = self
}
func updateResults(for query: String) {
print("🔍 검색어: \(query)")
results = dummyData.filter { $0.localizedCaseInsensitiveContains(query)}
tableView.reloadData()
}
}
// MARK: - Extension: UITableViewDataSource
extension KeywordResultsViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return results.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell()
cell.textLabel?.text = results[indexPath.row]
return cell
}
}