2์ 22์ผ (ํ)
- UISearchController
ย
[UISearchController]
https://developer.apple.com/documentation/uikit/uisearchcontroller
๋ฉ๋ชจ์ฅ ์ฑ์ ๊ฒ์ํ๋ ๊ธฐ๋ฅ์ ์ด๋ป๊ฒ ๊ตฌํํ ์ ์์๊น?
Navigation Item์๋ searchController
๋ผ๋ ํ๋กํผํฐ๊ฐ ์กด์ฌํ๋ค.
์ฌ๊ธฐ์ UISearchController
๋ฅผ ์์ฑํ์ฌ ํ ๋นํด์ค๋ค.
let searchController = UISearchController(searchResultsController: nil) // ๊ฒ์ ์ปจํธ๋กค๋ฌ ์์ฑ
searchController.searchBar.placeholder = "Search" // placeholder ํ ๋น
searchController.hidesNavigationBarDuringPresentation = false // ์คํฌ๋กค์ ๋ค๋น๊ฒ์ด์
๋ฐ๋ฅผ ์จ๊ธธ๊ฑด์ง ์ฌ๋ถ
searchController.searchResultsUpdater = self // delegate
searchController.searchBar.delegate = self // delegate
searchController.searchBar.setShowsCancelButton(false, animated: false) // ๊ฒ์๋ฐ์ cancel ๋ฒํผ์ ๋ณด์ฌ์ค์ง ์ฌ๋ถ
navigationItem.searchController = searchController // ๋ค๋น๊ฒ์ด์
์์ดํ
ํ ๋น
navigationItem.hidesSearchBarWhenScrolling = true // ์คํฌ๋กค์ ๊ฒ์๋ฐ๋ฅผ ์จ๊ธธ๊ฑด์ง ์ฌ๋ถ
์ถ๊ฐ๋ ๊ฒ์๋ฐ
- ์คํฌ๋กค์ ๋ด๋ ธ์ ๋ ๋ํ๋๋ ๊ฒ์๋ฐ
- ์งํํ๊ณ ์๋ ํ๋ก์ ํธ๋ ์ฝ์ด๋ฐ์ดํฐ๋ฅผ ํ์ฉํ์ฌ ๋ฉ๋ชจ๋ฅผ ์ ์ฅํ๊ณ ์๋ ํํ์๋ค.
NSPredicate
๋ฅผ ํ์ฉํ์ฌ ํํฐ๋งํ์ฌfetch
๋ฅผ ์งํํ๋ค.- ๊ทธ๋ฆฌ๊ณ tableView๋ฅผ
reload
ํด์ค๋ค.
final class PersistentManager {
private(set) var notes = [Note]() // ๋ทฐ์ ๋ณด์ฌ์ค ๋ฐ์ดํฐ๋ฅผ ๋ด์๋๋ ๋ฐฐ์ด
...
@discardableResult
func fetch( // ์ ์ฅ๋ ์ฝ์ด๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๋ ๋ฉ์๋
entityName: String = "Note",
predicate: NSPredicate? = nil,
sortDescriptors: [NSSortDescriptor]? = [NSSortDescriptor(key: "lastModified", ascending: false)]
) -> [Note]? {
let context = persistentContainer.viewContext
let request = NSFetchRequest<NSManagedObject>(entityName: entityName)
request.predicate = predicate
request.returnsObjectsAsFaults = false
request.sortDescriptors = sortDescriptors
guard let newData = try? context.fetch(request) as? [Note] else {
return nil
}
return newData
}
...
func setUpNotes() { // fetch๋ฅผ ํ์ฉํ์ฌ notes๋ฅผ ์ค์ ํ๋ ๋ฉ์๋
guard let newData = fetch() else {
return
}
self.notes = newData
}
...
๋ด ๊ฒฝ์ฐ์๋ ์ฝ์ด๋ฐ์ดํฐ๋ฅผ ๊ด๋ฆฌํ๋ ํ์ ๋ด๋ถ์์ tableView์ ๋ณด์ฌ์ง ๋ฐ์ดํฐ๋ ๊ฐ์ด ๊ด๋ฆฌํ๊ธฐ ๋๋ฌธ์, fetch๋ฅผ ๋ฐ์์จ ๋ค์ ๋ฐฐ์ด์ ํ ๋นํด์ฃผ๋ ๊ธฐ๋ฅ์ ์ถ๊ฐํ์ฌ ์งํํด์ฃผ์๋ค.
final class PersistentManager {
private(set) var notes = [Note]()
...
func searchNote(text: String) {
guard let searchData = fetch(
predicate: NSPredicate(format: "body CONTAINS[c] %@", text) // body์ text๊ฐ ํฌํจ๋์ด์๋ ๊ฒ๋ค์ ํํฐ๋ง
) else {
return
}
self.notes = searchData
}
...
- ๋ฐ๋ผ์ ์์ ๊ฐ์
searchNote(text:)
๋ผ๋ ๋ฉ์๋๋ฅผ ๊ตฌํํด์ฃผ์๋ค.
extension NotesViewController: UISearchResultsUpdating {
func updateSearchResults(for searchController: UISearchController) {
guard let searchText = searchController.searchBar.text, searchText != "" else { // ๊ฒ์์ด๊ฐ ๋น์ด์๋ค๋ฉด return
return
}
PersistentManager.shared.searchNote(text: searchText)
tableView.reloadData()
}
}
- ๊ทธ๋ฆฌ๊ณ
UISearchResultsUpdating
๋ฅผ ์ฑํํ์ฌ updateSearchResults(for:) ๋ฉ์๋๋ฅผ ๊ตฌํํ์ฌ ์์์ ๋ง๋ค์๋ searchNote ๋ฉ์๋๋ฅผ ํธ์ถํ๊ณ ํ ์ด๋ธ๋ทฐ๋ฅผreload
์์ผ์ฃผ์๋ค.
- ๊ฒ์์ด๋ฅผ ์ง์๋ ์๊น ๊ฒ์ํ๋ ๋ฉ๋ชจ๋ง ๋จ์์๋ค.
- ์ฆ, ๋ค์ ๋ฉ๋ชจ์ ์ ์ฒด ๋ชฉ๋ก์ ๋ณด๋ ค๋ฉด ์ฑ์ ๊ป๋ค ์ผ์ผํ๋... ํ์์ด ๋ํ๋ ๊ฒ์ด๋ค.
- ๋ฐ๋ผ์ UISearchBarDelegate๋ฅผ ํ์ฉํด์ ์๋์ ๊ฐ์ด ๊ตฌํํด์ฃผ์๋ค.
extension NotesViewController: UISearchBarDelegate {
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
guard searchBar.text == "" else { // ๊ฒ์์ด๊ฐ ๋น์ด์์ง ์๋ค๋ฉด return
return
}
PersistentManager.shared.setUpNotes() // ๊ฒ์์ด๊ฐ ๋น์ด์๋ค๋ฉด ๋ค์ notes๋ฅผ ์ค์ ํ๋ ๋ฉ์๋๋ฅผ ํธ์ถํ๊ณ
tableView.reloadData() // tableView๋ฅผ reloadํ๋ค.
}
}
- ์ ๋ฉ์๋๋ ํ ์คํธ๊ฐ ๋ณ๊ฒฝ๋ ๋๋ง๋ค ํธ์ถ๋๋ ๋ฉ์๋์ด๋ค.
๊ฒ์์ด๊ฐ ์กด์ฌํ์ง ์๋ค๋ฉด ์ ์ฒด๋ชฉ๋ก์ ๋ณด์ฌ์ฃผ๋ ๋ชจ์ต