iOS/StoryBoard

UISearchBar를 사용해서 목록 검색하기

소재훈 2022. 2. 1. 23:38

스토리보드 라이브러리에서 Search Bar를 선택해서 간단하게 검색창을 놓을 수 있다.

데이터는 Item이라는 이름의 entity이고, title과 done 이라는 프로퍼티가 엔티티에 지정되어 있다.

서치바의 기능을 사용하기 위해서는 클래스에 UISearchBarDelegate 클래스를 상속해야한다. Delegate가 포함된 클래스를 상속받을 때에는 항상 delegate를 지금 구현해야 하는 클래스로 바꾸어 주는 것을 잊지 말자. 

searchBar.delegate = self

위와 같이 코드로 작성해주거나, 아래와 같이 스토리 보드 파일에서 직점 설정해 줄 수 있다.

control(⌃)을 누른 채로, 뷰 상단에 가져다 대면 delegate로 설정할 수 있다.

 

//MARK: - Search bar methods
extension ToDoListViewController: UISearchBarDelegate {
    func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
        let request: NSFetchRequest<Item> = Item.fetchRequest()
        let predicate = NSPredicate(format: "title CONTAINS[cd] %@", searchBar.text!)
        
        request.predicate = predicate
        request.sortDescriptors  = [NSSortDescriptor(key: "title", ascending: true)]
        
        loadItems(with: request)
        tableView.reloadData()
    }
}

원래 구현하고 있던 클래스에 그대로 구현해버리면, 코드의 가독성이 떨어지고, 유지보수가 어려워지므로, extension을 통해 구분하기 쉽도록 해주었다. 우리가 지금 구현할 함수는 searchBarSearchButtonClicked(_  searchBar:)이다. 검색창에서 Search버튼이 눌렸을 때 호출되는 함수이다.

 

Item 엔티티에 대한 request를 작성하는 것이기 때문에 NSRequestFetch 사용자가 검색창에 문자열을 입력했을 때, 해당하는 문자열이 포함되어 있는 결과를 뽑아내기 위한 request를 작성하기 위해서 NSPredicate를 사용한다. format에는 쿼리를 입력하는데, title 프로퍼티(문자열) 에 검색창에 입력한 문자열이 포함된 엔티티만을 걸러낸다. NSPredicate의 format형식은 NSPredicate Cheat Sheet 에서 확인 할 수 있다.

NSSortDescriptor를 이용해 title 프로퍼티를 기준으로 문자열 오름차순으로 정렬하는 request를 작성하였다.

 

만들어진 request를 loadItems함수의 매개변수로 보내면, context.fetch(request)를 수행해 주고, 그 결과를 itemArray에 출력해준다.

func loadItems(with request: NSFetchRequest<Item> = Item.fetchRequest()) {
    do {
        itemArray = try context.fetch(request)
    } catch {
        print("Error fetching data from context \(error)")
    }
}

 

하지만 검색을 취소하고, 다시 원래의 전체 Item목록을 볼 수 없다는 문제가 있다. 이는 다음 포스트에서 해결해 보자.