본문 바로가기
카테고리 없음

[Swift] 책검색 App (3) - SearchBar 검색탭 구현

by 야고이 2024. 5. 6.
728x90

ui 그리는건 생략할게요! 그 와중에 하트버튼 위치는 수정해야함,,,

검색 결과 담을 빈배열 생성

var searchBookDocuments: [Document] = []

 

책을 검색하는 메서드 생성

func searchBook(keyword: String) {

파라미터로 검색할 키워드를 문자열로 받습니다

BookManager.shared.fetchBookData(withQuery: keyword, targets: [.title, .person]) { [weak self] success, response in

책 데이터를 가져오는 메서드를 호출 합니다

쿼리에는 검색하는 키워드를 넣고, 검색 대상(target) 은 title 과 person 에서 검색할게요

이 메서드는 비동기적으로 작동하며, 네트워크 요청이 완료 되면 클로저가 호출 됩니다

클로저 내부에서는 성공여부와 응답데이터를 확인합니다

sucess 는 Bool 값으로 true이고 응답데이터가 존재하면 데이터를 빈 배열에 저장합니다

self?.searchBookDocuments = response.documents

// 테이블뷰 리로드
self?.tableView.reloadData()

검색결과는 테이블뷰로 그렸습니다

검색한 데이터를 받아오면 그려준 테이블뷰를 다시 로드합니다

 

 

메서드 전체 코드

func searchBook(keyword: String) {
    print("searchBook \(keyword)")
    // api 통신
    BookManager.shared.fetchBookData(withQuery: keyword, targets: [.title, .person]) { [weak self] success, response in
        if success, let response = response {

            // 결과값 모델
            self?.searchBookDocuments = response.documents

            // 테이블뷰 리로드
            self?.tableView.reloadData()
        }
        else {
            // TODO: error UI

        }
    }
}

 

 

검색한 책 목록 업데이트 메서드 생성

func updateData(_ data: Document) {
    title.text = data.title
    author.text = data.authors.joined(separator: ", ")
    salePrice.text = String((data.salePrice).formatted(.currency(code: "KRW")))
    image.loadFromURL(data.thumbnail)
}

셀에 설정한 속성들을 검색한 값으로 업데이트 해주는 메서드를 만들어줍니다

업데이트는 셀에서 하므로 셀 파일에 메서드를 생성해 줍니다

 

author 는 배열로 받아오기 때문에 작가가 여러명일 수 있습니다 .joined(separator) 로 하나의 문자열로 합칩니다

가격을 화폐단위로 변환 하기 위해 formatted 를 사용합니다

 

 

URL 로 가져온 이미지를 로드하여 이미지뷰에 표시하는 메서드 생성

extension UIImageView {
    func loadFromURL(_ urlString: String) {
        guard let url = URL(string: urlString) else { return }
        DispatchQueue.global().async { [weak self] in
            if let data = try? Data(contentsOf: url) {
                if let image = UIImage(data: data) {
                    DispatchQueue.main.async {
                        self?.image = image
                    }
                }
            }
        }
    }
}

 

다시 셀을 생성하는 곳으로 가볼게요,,,

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    searchBookDocuments.count
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    guard let cell = tableView.dequeueReusableCell(withIdentifier: ResultTableViewCell.identifier, for: indexPath) as? ResultTableViewCell else { return ResultTableViewCell() }

    let item = searchBookDocuments[indexPath.row]
    cell.selectionStyle = .none //셀 선택시 하이라이트 효과 안하기
    cell.updateData(item)

    return cell
}

셀의 갯수는 배열에 담긴 갯수만큼 뿌려주고

배열에서 해당하는 셀을 item 를 담고

updateData 메서드를 사용해서 셀을 업데이트 합니다

 

검색시 검색 키워드 값 전달

extension SearchViewController: UISearchBarDelegate {
    func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
        guard let text = searchBar.text else { return }
        
        searchBar.resignFirstResponder() // 키보드 닫힘
        
        self.searchBook(keyword: text)
    }
}

서치바 서치버튼 클릭시  입력한 문자열이 searchBook 메서드의 파라미터로 전달 됩니다

 

 

휴 드디어 검색결과 불러옴!

추가적으로 설정한 사항 중에 기록할 만한것도 남겨 놓을게요


 

서치바 기본 색상 변경

searchBar.searchTextField.backgroundColor = .white

서치바에 기본 색상이 들어가있는데 그 색상을 바꿔주는 코드 입니다

 

뷰 클릭시 키보드 내리기

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?){
    print("touchesBegan")
    self.view.endEditing(true) // 현재 뷰의 모든 편집상태 종료
}

touchesBegan 메서드는 사용자의 터치가 화면에서 시작될 때 호출 된다

self.view.endEditing(true) 이코드를 넣으면 터치 이벤트가 발생했을 떄 키보드 외의 영역을 터치했을 때 키보드를 닫아줍니다

근데 테이블뷰를 올리니 뷰가 다 가려져서 터치이벤트가 안먹었다

func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
    print("scrollViewWillBeginDragging")
    self.view.endEditing(true)
}

UIScrollViewDelegate를 채택하고 

scrollViewWillBeginDragging 메소드는 스크롤이 시작될 때 호출 됩니다

여기에도 뷰를 터치하면 모든 편집상태가 종료 됩니다

한마디로 키보드가 내려감!!

 

728x90

댓글