네비게이션 요소 - 서치바(searchBar) 구현하기

임혜정·2024년 5월 17일
0

실습/예제 정리

목록 보기
18/21

서치바(search fields)

사용자의 입력값을 받아 범위 데이터 내에서 해당하는 데이터를 찾아주는 역할


구현하는 법?

검색필드를 모두 textfield로 구현하는 줄 알았는데 방법이 두 가지 였다. textfield와 searchbar가 있고 각 이름에 맞는 delegate를 쓴다.

차이점.
UITextField는 표현 자유도높음, 기본검색기능이 없어서 구현해줘야함
UISearchBar는 자유도낮음, 기본 제공 기능이 많아 자리많이차지함. 그러나 일관적

EX)

  • 특별히 디자인된 서치바를 쓰고싶고 기능도 커스터마이징해서 최소한의 or 특별한 기능을 추가해서 쓸거야! -> UITextField
  • 일관되게 애플 스타일의 서치바를 쓰고싶고 음..좀 시간이없고 귀찮아 -> UISearchBar
    .
    .

나는 텍스트필드는 만들어본 적이 있어서 오늘은 searchBar를 한번 써보고싶다.


UISearchBar를 구현할 때에 주로 사용되는 프로토콜은 UISearchBarDelegate이다. 그리고 그에 따라 사용할 수 있는 메서드는 다음과 같다.

  • searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) 검색 텍스트가 변경될 때 호출
  • searchBarSearchButtonClicked(_ searchBar: UISearchBar) 검색 버튼이 클릭될 때 호출
  • searchBarCancelButtonClicked(_ searchBar: UISearchBar) 취소 버튼이 클릭될 때 호출
  • searchBarTextDidBeginEditing(_ searchBar: UISearchBar) 검색 바에서 텍스트 편집이 시작될 때 호출
  • searchBarTextDidEndEditing(_ searchBar: UISearchBar) 검색 바에서 텍스트 편집이 끝날 때 호출

서치바의 어떤 기능을 부여할 지는 때에 따라 달라질 수 있어서 필요한 것만 갖다쓰면된다. 그 중에 searchBarSearchButtonClicked는 필수적으로 쓸 것 같다.


오늘 해보고 싶은 것

텍스트필드에 무언가를 입력하고 엔터나 서치버튼을 누르면 그 입력값을 라벨에 반영되게 해보고 싶다.


과정

서치바와 라벨을 추가하고 뷰 컨트롤러에 연결해준다.

extension ViewController: UISearchBarDelegate {
    func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
        resultLabel.text = searchBar.text
        searchBar.resignFirstResponder()
    }
}

그리고 UISearchBarDelegate프로토콜을 채택하고 searchBarSearchButtonClicked메서드를 이용하여 서치바에 입력 후 엔터를 누르면 입력값을 라벨에 표시되게끔 해준다. 코드를 보기 쉽고 재활용이 용이하도록 extension으로 빼서 작성했다.

?앵? 너무 간단했다..ㅋㅋ
그러나 몇 가지 문제가 있었다.

  1. 가장 왼쪽 돋보기 아이콘이 그저 시각적인 요소일 뿐, 아무 기능도 없다는 것. 가능하다면 저 아이콘에도 동작을 부여하고 싶다. 내가 사용자일 때에는 검색하고 싶은 텍스트를 입력하고나서 주로 키보드의 search, return..↩️ 으로 검색하지만 어떤 사람들은 돋보기 아이콘을 누를 수도 있지않을까?
  2. 검색하고 난 뒤에 서치필드가 아무 것도 없는 상태로 리셋되었으면 좋겠다.
  3. 한번 검색하고 난 뒤 두번째로 뭔가 입력하기 위해 서치필드를 클릭했을 때 키보드가 자동으로 올라오지 않는다.

  1. searchBar의 돋보기 아이콘에 접근이 하고 그에 기능을 부여하는 것이 가능하다.
extension ViewController { 
    func configureSearchBar(){ // 돋보기아이콘에 접근
        if let searchBarTextField = searchBar.value(forKey: "searchField") as? UITextField,
           let leftView = searchBarTextField.leftView {
            let tapGesture = UITapGestureRecognizer(target: self, action: #selector(didTapSearchIcon))
            leftView.addGestureRecognizer(tapGesture)
            leftView.isUserInteractionEnabled = true
        }
    }
    @objc func didTapSearchIcon() { // 아이콘 누르면 라벨에 업데이트
        resultLabel.text = searchBar.text
    }
}

잘된다. 그렇지만 리턴버튼과 정확히 같은 동작을 실행하게 할 것이므로 재사용 가능하게 updateResultLabel 함수에 정의한다.

import UIKit

class ViewController: UIViewController {
    
    @IBOutlet weak var searchBar: UISearchBar!
    @IBOutlet weak var resultLabel: UILabel!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        searchBar.delegate = self
        configureSearchBar()
    }
    func updateResultLabel(with text: String?) {
        resultLabel.text = text
        searchBar.text = " " //서치필드 텍스트 초기화
        searchBar.resignFirstResponder()
    } // return키와 돋보기아이콘의 동작
    
}

extension ViewController: UISearchBarDelegate {
    func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
        updateResultLabel(with: searchBar.text)
    }
    func searchBarTextDidBeginEditing(_ searchBar: UISearchBar) {
        // 키보드 강제토글
        searchBar.becomeFirstResponder()
    }
}
extension ViewController {
    func configureSearchBar(){ // 돋보기아이콘에 접근
        if let searchBarTextField = searchBar.value(forKey: "searchField") as? UITextField,
           let leftView = searchBarTextField.leftView {
            let tapGesture = UITapGestureRecognizer(target: self, action: #selector(didTapSearchIcon))
            leftView.addGestureRecognizer(tapGesture)
            leftView.isUserInteractionEnabled = true
        }
    }
    @objc func didTapSearchIcon() { // 돋보기 아이콘을 누를 시 return키와 같은 동작.
        updateResultLabel(with: searchBar.text)
    }
}

텍스트필드 키보드 토글 안됨

  • 한번 검색한 뒤에 키보드가 올라오지 않아서 강제로 올라오도록 코드를 추가하였으나 시뮬레이터에서는 먹히지 않았다. cmd + k로 다시 올려야되는 듯
  • 이런 문제가 생기는 이유는 시뮬레이터에서 맥북의 키보드로 타이핑과 리턴을 누르고 난 뒤부터는 키보드가 올라오지 않았다.
  • 따라서 시뮬로 테스트를 할 때에 실제 핸드폰을 조작하듯이 마우스로 토글된 키보드버튼으로만 조작하면 그 다음 검색 때도 키보드가 잘 올라온다.

더 쉬운 해결

위와 같은 방식에 대해 고민하고 있다고 하니 매니저님께 추천받은 방법

돋보기 아이콘 위에 버튼을 추가함. button텍스트를 지우고 아이콘 범위까지로 설정해주면 눈에는 보이지 않지만 투명한 버튼이 존재하고 있는 것이다.


이렇게. 그럼 투명한 버튼이 서치바위에 올라가있는 형태일 것이다.

그 버튼을 액션으로 뷰컨트롤러에 연결하고 동작함수를 넣어준다. 훨씬 간단하게 가능했다.
내가 뭘 만들고 있는지 뭘 생각하는지 말을 많이하면 다른 좋은 방법과 생각들이 쏟아진다. ㅎㅎ

profile
오늘 배운걸 까먹었을 미래의 나에게..⭐️

0개의 댓글