사용자의 입력값을 받아 범위 데이터 내에서 해당하는 데이터를 찾아주는 역할
검색필드를 모두 textfield로 구현하는 줄 알았는데 방법이 두 가지 였다. textfield와 searchbar가 있고 각 이름에 맞는 delegate를 쓴다.
차이점.
UITextField는 표현 자유도높음, 기본검색기능이 없어서 구현해줘야함
UISearchBar는 자유도낮음, 기본 제공 기능이 많아 자리많이차지함. 그러나 일관적
EX)
나는 텍스트필드는 만들어본 적이 있어서 오늘은 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으로 빼서 작성했다.
?앵? 너무 간단했다..ㅋㅋ
그러나 몇 가지 문제가 있었다.
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텍스트를 지우고 아이콘 범위까지로 설정해주면 눈에는 보이지 않지만 투명한 버튼이 존재하고 있는 것이다.
이렇게. 그럼 투명한 버튼이 서치바위에 올라가있는 형태일 것이다.
그 버튼을 액션으로 뷰컨트롤러에 연결하고 동작함수를 넣어준다. 훨씬 간단하게 가능했다.
내가 뭘 만들고 있는지 뭘 생각하는지 말을 많이하면 다른 좋은 방법과 생각들이 쏟아진다. ㅎㅎ