【Swift】TableView에서 검색한 것만 표시

소개



이번에는 검색한 문자열만 TableView에서 표시합니다. 다음과 같은 것을 만들어 보겠습니다.


GitHub



구현



1.Main.storyboard에서 다음과 같이 UITextFieldUITableView 를 배치한다.

2. 문자열을 넣어 두는 배열과 검색된 것을 넣어 두는 배열을 준비한다.

ViewController
private var datas = [String]()
private var filterdDatas = [String]()

3. 앞서 준비한 배열에 viewDidLoad() 로 데이터를 저장한다.

ViewController
datas.append("Swift")
datas.append("Java")
datas.append("Ruby")
datas.append("C++")
datas.append("C")
datas.append("C#")
datas.append("Python")
datas.append("Perl")
datas.append("JavaScript")
datas.append("PHP")
datas.append("Scratch")
datas.append("Scala")
datas.append("COBOL")
datas.append("Curl")
datas.append("Dart")
datas.append("HTML")
datas.append("CSS")

4. delegate 사용

ViewController
tableView.delegate = self
tableView.dataSource = self
tableView.tableFooterView = UIView() // 不要なセパレーターが表示されなくなります
textField.delegate = self

5. UITableViewDelegate 구현

ViewController
extension ViewController: UITableViewDelegate {
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return 60 // 適当に高さを60にしておきます
    }
}

6. UITableViewDataSource 구현

ViewController
extension ViewController: UITableViewDataSource {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        if !filterdDatas.isEmpty {
            return filterdDatas.count
        }
        return datas.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
        cell.textLabel?.text = filterdDatas.isEmpty ? datas[indexPath.row] : filterdDatas[indexPath.row]
        return cell
    }
}
filterdDatas 가 비어 있으면, datas.count 를, 무엇인가 들어 있으면 filterdDatas.count 를 돌려줍니다.

7. UITextFieldDelegate 구현

ViewController
extension ViewController: UITextFieldDelegate {
    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        if let text = textField.text {
            (string.count == 0) ? filterText(String(text.dropLast())) : filterText(text+string)
        }
        return true
    }

    func filterText(_ query: String) {
        filterdDatas.removeAll()
        datas.forEach { data in
            if data.lowercased().starts(with: query.lowercased()) {
                filterdDatas.append(data)
            }
        }
        tableView.reloadData()
    }
}
textField 의 델리게이트 메소드 shouldChangeCharactersIn 는 문자가 입력될 때마다 처리가 불리는 메소드입니다 ( 참고 기사 )(string.count == 0) ? filterText(String(text.dropLast())) : filterText(text+string)string 는 입력한 문자가 한 문자입니다. 이것이 0 즉, textField 의 문자를 소거했을 때에 text.dropLast() 합니다. ( 참고 기사 )lowercased() 에서 대문자를 모두 소문자로 변환하고 있습니다. ( 참고 기사 )starts(with: ) 에서 시퀀스의 첫 번째 요소가 다른 시퀀스의 요소와 같은지 여부를 부울 값으로 반환합니다. 즉, 대문자 소문자를 구별하지 않고, 입력된 값의 querydata 가 완전하게 포함되어 있으면 true 가 됩니다.
그리고 문자가 입력될 때마다 tableView 를 갱신해 줍니다.

8. 신고하기
이 상태로 검색 결과가 없을 때는 모두 표시됩니다. 
그러므로, 플래그를 세워 해당하는 문자가 있을지 어떨지를 판단합니다.

ViewController
private var isFilterd = false

그런 다음 tableView.reloadData() 아래에 isFilterd = true를 추가하여 numberOfRowsInSectionreturn isFilterd ? 0 : datas.count로 변경합니다.

결론



끝입니다.

좋은 웹페이지 즐겨찾기