seong_hye, the developer

Swift) UISearchController에 대해 알아보기 본문

IOS/UIKit

Swift) UISearchController에 대해 알아보기

seong_hye 2022. 11. 8.

 

📘UISearchController

UIKit에서 공식적으로 제공하는 검색 UI 컨트롤러

검색 바 (SearhBar) + 검색 결과 처리 (SearchResultsController)를 결합해주는 역할

UITableView나 UICollectionView와 함께 자주 사용됨


🔹핵심 구성 요소

구성 요소 설명
searchBar 사용자가 검색어 입력하는 UI
searchResultUpdater 입력된 텍스트에 따라 결과 업데이트 
searchResultsController 검색 결과를 표시할 뷰컨 (옵션, 기본은 현재 뷰)
obscuresBackgroundDuringPresentation 검색 중 배경 흐림 여부 (보통 false로 설정)
definesPresentationContext 다른 화면 전환 시 검색 바 상태 유지 여부
searchController.isActive 현재 검색 중인지 여부

🔹사용 예시

let searchController = UISearchController(searchResultsController: nil)

// 검색 컨트롤러 설정
searchController.searchResultsUpdater = self
searchController.obscuresBackgroundDuringPresentation = false
searchController.searchBar.placeholder = "검색"
navigationItem.searchController = searchController
navigationItem.hidesSearchBarWhenScrolling = false 		// 검색바가 기본으로 보이도록 설정
definesPresentationContext = true						// 화면 간 검색 바 유지 방지

// 검색 결과 필터링
func updateSearchResult(for searchController: UISearchController) {
	let searchText = searchController.searchBar.text ?? ""
    filteredItems = allItems.filter { $0.localizedCaseInsensitiveContains(searchText)}
   	tableView.reloadData()
}

⚠️ iPad에서는 searchController 또는 내부 결과 화면이 Popover로 나타날 수 있으므로

definesPresentationContext = true 설정을 반드시 넣어줘야 예외가 발생하지 않음

 

✅ 예시 화면


🔹확장 기능

- 검색 버튼 누를 때 동작

UISearchBarDelegate의 searchBarSearchButtonClicked(_:) 사용

// 검색 UI 연결
searchController.searchBar.delegate = self

// 버튼 동작 처리
func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
	let query = searchBar.text ?? ""
    filteredItems = allItems.filter { $0.licalizedCaseInsensitiveContains(query)}
    tableView.reloadData()
    searchBar.resignFirstResponder() // 키보드 내리기
}

 

- Scope 버튼 (범위 선택)

searchBar.scopeButtonTitles = ["전체", "제목", "작성자"]

let allItems = ["[제목] Swift", "[내용] iOS", "[제목] UIKit", "[내용] Combine"]

//scope 버튼 설정
scrachController.searchBar.scopeButtonTitles = ["전체","제목","내용"]

//scope 버튼이 바뀔 때
func searchBar(_ searchBar: UISearchBar, selectedScopeButtonIndexDidChange selectedScope: Int) {
	applyFiltering()
}

func applyFiltering() {
	let query = searchController.searchBar.text ?? ""
    let scopeIndex= searchController.searchBar.selectedScopeButtonIndex
    let scope = searchController.searchBar.scopeButtonTitles?[scopeIndex] ?? "전체"
    
    filteredItems = allItems.filter { item in
    	if scope == "전체" {
        	return item.localizedCaseInsensitiveContains(query)
        } else {
        	return item.hasPrefix("[\(scope)") && item.localizedCaseInsensitiveContains(query)
        }
    }
    tableView.reloadData()
}

 

✅ Scope 결과 화면


🔹SwiftUI에서 사용 방법

UIKit의 UISearchController를 직접 쓰진 않고

List, NavigationStack 안에 .searchable() 수식어를 사용

struct SearchView: View {
	@State private var searchText = ""
    
    var body: some View {
    	NavigationStack {
        	List {
            	// 목록
            }
            .searchable(text: $searchText, prompt: "검색어 입력")
        }
    }
}

 

Comments