[iOS] Search Bar

RudinP·2024년 4월 30일
0

Study

목록 보기
223/227

코드로 서치바 추가하기

override func viewDidLoad() {
        super.viewDidLoad()
        
        let searchBar = UISearchBar()
        searchBar.placeholder = "검색"
        searchBar.showsCancelButton = true
        
        navigationItem.titleView = searchBar
}
  • 해당 vc를 가진 씬은 네비게이션 vc에 임베드 되어있어야 함

titleView에는 뷰를 넣을 수 있다.

  • 따라서 스택뷰를 넣는 것도 가능하다.
let btn = UIButton(type: .custom)
btn.setTitle("취소", for: .normal)
btn.setTitleColor(.systemOrange, for: .normal)
btn.addTarget(self, action: #selector(closeVC), for: .touchUpInside)
btn.widthAnchor.constraint(greaterThanOrEqualToConstant: 40).isActive = true
        
let stack = UIStackView(arrangedSubviews: [searchBar, btn])
stack.axis = .horizontal
stack.spacing = 8
        
navigationItem.titleView = stack
  • 그러나 이렇게 추가하면 스택뷰의 너비 제약이 없어 서치바가 표시되지 않는다. 따라서 너비 제약을 추가해야 한다.
stack.widthAnchor.constraint(greaterThanOrEqualToConstant: view.bounds.width - 40).isActive = true

delegate

  • cancel버튼을 동작하게 하려면 delegate를 구현해야 한다.
  • viewdidload에서 당연히 델리게이트를 self로 지정하자.
searchBar.delegate = self

  • CancelButtonClicked 델리게이트를 구현하면 Cancel 버튼을 누를 시 동작을 구현할 수 있다.

textDidChange

  • 서치바에 입력할때마다(즉, 텍스트가 변경될때마다) 호출된다.
  • 검색 기능은 여기서 구현하면 된다.
extension CitySelectionViewController: UISearchBarDelegate{
    func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
        //공백을 입력할 경우 별도로 서치 필요 X, 모든 결과를 보여주기
        guard !searchText.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty else {
            filteredList = list
            tableView.reloadData()
            tableView.isHidden = filteredList.isEmpty
            return
        }
        //검색어가 입력되었을 경우
        //이전 검색 시 사용했을 경우를 위해 removeAll로 배열 초기화
        filteredList.removeAll()
        
        for section in list{
            let items = section.items.filter{ $0.title.lowercased().contains(searchText.lowercased()) }
            
            //비어있지 않은 경우 == 검색 결과 존재
            if !items.isEmpty {
                filteredList.append(Section(title: section.title, items:  items))
            }
        }
        
        tableView.reloadData()
        tableView.isHidden = filteredList.isEmpty
    }
}

  • 만약 검색 결과가 존재하지 않을 경우, 검색 결과 없음을 표시하고 싶다면 레이블을 테이블뷰 뒤에 추가하면 된다.
  • 검색 결과가 없을 경우 테이블뷰가 표시되지 않도록 tableView.isHidden = filteredList.isEmpty로 해뒀기 때문에 때문에 별도로 아웃렛을 연결하여 처리할 필요는 없다.

profile
곰을 좋아합니다. <a href = "https://github.com/RudinP">github</a>

0개의 댓글