ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • UISearchBar에서 사용자가 입력을 멈췄을 때 자동으로 검색하기(실시간 검색)
    iOS/Swift 2022. 1. 11. 23:36

    안녕하세요!! 이번엔 UISearchBar를 이용해서 실시간 검색을 구현하는 방법을 정리했습니다.

    이번 글도 노션에서 옮겨와 말이 짧습니다!! 양해해주세용😽


     

    UISearchBar에서 글자를 입력할 때, 일정 시간동안 텍스트가 더이상 추가, 삭제되지 않으면 그 텍스트를 검색하는 기능을 추가하고 싶어서 이것저것 검색해보았다.

     

    먼저, 일정 시간이 지났는지 확인하기 위해 Timer를 추가해주었다.

    var searchTimer: Timer?
    

    UISearchBar의 텍스트 값이 변하는 것을 어떻게 알 수 있을지 고민했는데,

    UISearchBar의 Delegate 메서드 중에 UISearchBar의 텍스트 값이 변하면 호출되는 메서드가 있었다.

     

    viewDidLoad에서 UISearchBar를 delegate하고 메서드를 사용할 준비를 한다.

    override func viewDidLoad() {
            super.viewDidLoad()
            searchBarConfig()
            
            tableView.delegate = self
            tableView.dataSource = self
            tableView.backgroundColor = UIColor(named: "AccentColor")
            
            searchBar.delegate = self
        }
    

     

    UISearchBar의 텍스트가 바뀔 때 호출되는 메서드는 textDidChange 메서드다.

    extension SearchViewController: UISearchBarDelegate {
        func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
            
            self.searchTimer?.invalidate()
            self.searchTimer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: false, block: { timer in
                self.searchStart()
                if self.searchResult.isEmpty {
                    print("검색 결과 없음")
                }
            })
        }
        
        func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
            self.searchStart()
            if self.searchResult.isEmpty && !searchBar.text!.isEmpty {
                let alert = UIAlertController(title: nil, message: "검색 결과가 없습니다.", preferredStyle: .alert)
                let okButton = UIAlertAction(title: "확인", style: .default, handler: nil)
                alert.addAction(okButton)
                present(alert, animated: true, completion: nil)
            }
            searchBar.resignFirstResponder()
        }
        
    }
    

    값이 바뀔 때 마다 타이머가 예약되니까 메소드가 호출될 때 이전의 타이머를 invalidate 메서드로 무효화 시켜주었다.

    그 이후에 Timer를 다시 설정하고,

    값이 바뀌지 않으면 1초 뒤에 block에 있는 클로져가 실행돼서 self.searchStart 메서드를 실행할 수 있다.

    시간을 줄이고 싶다면, withTimeInterval의 값을 원하는 시간으로 줄여주면 된다.

    func searchStart() {
            searchResult = movies.filter( { ($0.korTitle! + $0.engTitle!).lowercased().contains(searchBar.text!)} )
            print(searchResult)
        }
    

    searchStart함수가 실행되면 searchResult라는 movie 객체를 담을 수 있는 배열에 filter 함수에 만족하는 조건을 가진 movie 객체들이 담긴다.

     

    var searchResult = [Movie]() {
            didSet {
                tableView.reloadData()
            }
        }
    

    그리고 searchResult에는 프로퍼티 옵저버를 달아두고, 값이 바뀔 때 tableView를 reload시킬 수 있도록 만들었다 😃

     

     

    실행결과

    텍스트 값이 바뀔 때 마다 텍스트를 포함하는 영화나 드라마가 나타난다!

    댓글

Designed by Tistory.