Programming/iOS

[iOS/Swift] 자동 완성 기능 구현하기(swift auto completion by UISearchController)

devssun 2017. 8. 10. 10:06
728x90
반응형

Swift로 자동완성 기능 구현하기

참고 자료 : https://blog.apoorvmote.com/add-uisearchcontroller-to-tableview/?lang=ko


  • 필요한 것 : TableViewController, UISearchController


이전에는 UISearchDisplayController가 있었는데 iOS 8.0 이후 deprecated되었다

'자동완성'이라고 검색하면 아이폰에 내장된 자동완성 기능 관련한 글이 많아서 찾기 힘들었는데 ㅠ 그래도 나왔다! 다행히 프레임워크나 라이브러리없어도 충분히 가능한 것이었다

테이블뷰는 데이터를 뿌리기위해 필요했기 때문에 기타 다른 뷰에도 출력할 수 있을 것이라 생각한다

위의 사이트에는 다소 변역이 제대로 안되어있당



시작

  1. SingleView Application 생성
  2. Storyboard로 이동 후 ViewController삭제, TableViewController 끌어놓기
  3. tableView의 cell을 선택하여 identifier를 정의해준다 (안하거나 추후 swift파일에 작성한 id와 다르면 오류 발생함) (사진)
  4. UITableViewController를 Subclass로 설정하여 새로운 파일을 생성한다(File>New>File>Cocoa Touch Class)
  5. Storyboard에서 TableViewController를 선택한 뒤, identity inspector에서 Class를 연결해준다
  6. 파일 작성



  1. sample data와 UISearchController 뷰 만들기

    var tableData = ["One", "Two", "Three", "Four", "Five"]
    var filteredData:[String] = []
    var resultSearchController:UISearchController!
  2. viewDidLoad()에서 resultSearchController 초기화 세팅작업 사이트의 함수명과 조금 달라졌으나 동일한 함수이다

    // 1. 검색컨트롤러 인스턴스 생성
    resultSearchController = UISearchController(searchResultsController: nil)
    // 2. 검색 결과는 동일한 table view controller에 결과를 보여준다
    resultSearchController.searchResultsUpdater = self
    // 3. 검색컨트롤러는 검색하는 동안 네비게이션바에 가려지지않도록한다
    resultSearchController.hidesNavigationBarDuringPresentation = false
    // 4. 검색하는 동안 배경이 검은색으로 변경되지 않도록 한다
    resultSearchController.dimsBackgroundDuringPresentation = false
    // 5. 검색컨트롤러 스타일 설정
    resultSearchController.searchBar.searchBarStyle = UISearchBarStyle.prominent
    // 6. 검색컨트롤러의 사이즈를 화면에 맞도록 설정
    resultSearchController.searchBar.sizeToFit()
    // 7. 검색 컨트롤러는 테이블의 Header에 위치시킨다
    self.tableView.tableHeaderView = resultSearchController.searchBar
    // 8. presentation context 설정
    self.definesPresentationContext = true
  3. tableview setting

    // 섹션 설정, 보통 1로 한다
    override func numberOfSections(in tableView: UITableView) -> Int {
       // #warning Incomplete implementation, return the number of sections
       return 1
    }
     
    // 테이블뷰에 보여줄 데이터의 갯수
    // 검색컨트롤러가 활성화되면 필터된 데이터의 갯수, 비활성화라면 원본 데이터의 갯수를 리턴한다
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
       // #warning Incomplete implementation, return the number of rows
       if resultSearchController.isActive{
           return filteredData.count
       }else{
           return tableData.count
       }
    }
     
    // 테이블뷰의 cell에 보여줄 데이터 정의
    // 위에서 한 것처럼 검색컨트롤러가 활성화되면 필터된 데이터를 보여준다
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
         let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
     
         // Configure the cell...
         if resultSearchController.isActive{
             cell.textLabel?.text = filteredData[indexPath.row]
         }else{
             cell.textLabel?.text = tableData[indexPath.row]
         }
         return cell
     }


4. 클래스에 UISearchResultsUpdating 추가 후 아래 함수에 내용 작성하기

- updateSearchResults()는 UISearchResultsUpdating 클래스의 required 함수

Called when the search bar becomes the first responder or when the user makes changes inside the search bar. 

search bar가 응답받거나 내부 변화가 있을 때 호출된다

  func updateSearchResults(for searchController: UISearchController) {
          if (searchController.searchBar.text?.characters.count)! > 0{
              filteredData.removeAll(keepingCapacity: false)
              let searchPredicate = NSPredicate(format: "SELF CONTAINS %@", searchController.searchBar.text!)
              let array = (tableData as NSArray).filtered(using: searchPredicate)
              filteredData = array as! [String]
              tableView.reloadData()
          }else{
              filteredData.removeAll(keepingCapacity: false)
              filteredData = tableData
              tableView.reloadData()
          }
      }


완성!


반응형