[iOS] 영화예매앱 만들기[1] - 서치바 커스터마이징

Kiwi·2024년 4월 30일

iOS

목록 보기
14/15
post-thumbnail

📁 영화예매앱 만들기

  • 프로젝트 주제 : 영화예매 앱을 만들자!
  • 내가 맡은 기능 : 검색 기능과 탭바



🌳 View 구조 나누기

일단 내 뷰를 크게 top, body로 나누었다. top에는 서치바 있는 부분 SearchView가 들어가고, body에는 최신검색어가 나오는 부분인 LastSearchedView와 검색결과가 나오는 부분인 ResultView가 들어간다.



🌳 TopView - 서치바 커스터마이징

검색창을 보면 서치바를 사용하는 것 뿐만 아니라 커스텀까지 해야했다!!🙊🙉

서치바를 사용하는 방법은 tableView와 비슷한다. UISearchBarDelegate를 지정해줘야한다.
일단 먼저 서치바를 만들어주고 커스텀을 해준다.

lazy var searchBar: UISearchBar = {
        let search = UISearchBar()
        search.placeholder = "영화를 검색해보세요"
        search.searchBarStyle = .minimal
        search.searchTextField.borderStyle = .none
        search.delegate = self
        if let tf = search.value(forKey: "searchField") as? UITextField {
            if let leftView = tf.leftView as? UIImageView {
                leftView.tintColor = .megaRed
            }
        }
        return search
    }()

lazy var로 정의 : 초기화 시점을 지연시켜 메모리를 효율적으로 사용할 수 있다!! 이에 대해서는 나중에 꼼꼼히 정리해봐야겠음.

여기서 searchBar는 여러 키값을 가지고 있는데 searchField는 검색 바의 텍스트 필드에 직접 접근할 수 있게 해준다. 이를 value(forKey:)로 받아온 다음 UITextField로 다운캐스팅 해주었다.

여기서 텍스트필드에는 검색창 뿐만 아니라 옆에 검색 버튼도 있는데 이 버튼도 UIImageView로 다운캐스팅 해와서 색을 바꾸어 주었다!!

일단 요렇게 나온다.

다운캐스팅 한번 더 정리!

  • 안전한 다운캐스팅(as?): 다운캐스팅이 실패할 수 있는 경우에 사용. 다운캐스팅이 실패하면 nil을 반환.
  • 강제 다운캐스팅(as!): 다운캐스팅이 확실히 성공할 것으로 확신할 때 사용. 만약 다운캐스팅이 실패하면 런타임 에러가 발생.

여기서 나는 서치바 자체를 커스터마이징 하지 않고 뒤에 뷰를 하나 만들어주고 서치바를 투명하게 만들어주어서 마치 서치뷰가 동그란 것 처럼 했다!! 이 뷰에 그림자 효과도 주었다!!

let searchView: UIView = {
        let bgview = UIView()
        bgview.layer.shadowColor = UIColor.black.cgColor
        bgview.layer.shadowOpacity = 0.6
        bgview.layer.shadowOffset = CGSize(width: 0, height: 0)
        bgview.layer.shadowRadius = 5
        bgview.layer.masksToBounds = false
        bgview.layer.shouldRasterize = false
        bgview.backgroundColor = UIColor.white
        bgview.layer.borderWidth = 1
        bgview.layer.borderColor = UIColor.clear.cgColor
        bgview.layer.cornerRadius = 20
        return bgview
    }()

그런데 지금 정리하면서 서치바 자체를 커스텀 하는 것도 가능한 것을 발견! 왜 그때는 해볼 생각을 안했지? 🫤

lazy var searchBar: UISearchBar = {
        let search = UISearchBar()
        search.placeholder = "영화를 검색해보세요"
        search.layer.cornerRadius = 20
        search.layer.borderColor = UIColor.black.cgColor
        search.layer.borderWidth = 1
        search.searchBarStyle = .minimal
        search.searchTextField.borderStyle = .none
        search.layer.shadowColor = UIColor.black.cgColor
        search.layer.shadowOpacity = 0.6
        search.layer.shadowOffset = CGSize(width: 0, height: 0)
        search.layer.shadowRadius = 8
        search.layer.masksToBounds = false
        search.layer.shouldRasterize = false
        search.delegate = self
        if let tf = search.value(forKey: "searchField") as? UITextField {
            if let leftView = tf.leftView as? UIImageView {
                leftView.tintColor = .red
            }
        }
        return search
    }()

된다!



🌳 TopView - UISearchBarDelegate 설정하기

UISearchBarDelegate를 설정해줘야 한다. 안해주면 그냥 textField와 다름이 없음.. 그래서 얘의 역할이 뭐냐... UITableViewDelegate랑 같다. "UISearchBar 객체의 동작을 관리하기 위한 메서드와 속성을 정의" 한다.

주요 메서드 속성은 다음과 같다. (fromGPT)

  • searchBarSearchButtonClicked(_:): 사용자가 검색 버튼을 눌렀을 때 호출됩니다. 이 메서드를 사용하여 검색을 실행하거나 관련 작업을 수행할 수 있습니다.
  • searchBarCancelButtonClicked(_:): 사용자가 취소 버튼을 눌렀을 때 호출됩니다. 이 메서드를 사용하여 검색 작업을 취소하거나 관련 작업을 수행할 수 있습니다.
  • searchBar(_:textDidChange:): 사용자가 검색 바의 텍스트를 변경할 때 호출됩니다. 이 메서드를 사용하여 실시간 검색 결과를 업데이트하거나 관련 작업을 수행할 수 있습니다.
  • searchBar(_:selectedScopeButtonIndexDidChange:): 사용자가 검색 바의 범위 버튼(스코프 버튼)을 변경할 때 호출됩니다. 이 메서드를 사용하여 선택된 스코프에 따라 검색 동작을 조정하거나 관련 작업을 수행할 수 있습니다.
  • searchBarShouldBeginEditing(_:): 사용자가 검색 바를 편집하기를 시도할 때 호출됩니다. 이 메서드를 사용하여 검색 바를 편집할 수 있는지 여부를 결정할 수 있습니다.
  • searchBarTextDidBeginEditing(_:): 사용자가 검색 바를 편집하기 시작했을 때 호출됩니다. 이 메서드를 사용하여 편집 작업을 시작할 때 필요한 작업을 수행할 수 있습니다.

여기서 나는 서치바의 텍스트가 바뀌었을 때 바로 반영해서 결과를 보여줄수 있게 searchBar(:textDidChange:)와 서치바에서 서치를 눌렀을 때 최신검색어에 데이터를 저장하기 위해 searchBarSearchButtonClicked( searchBar: UISearchBar), 그리고 취소 버튼을 클릭했을 때의 처리를 위한 searchBarCancelButtonClicked(_:)를 사용!
코드는 다음과 같다.

extension SearchViewController: UISearchBarDelegate {
    func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
        print("사용자가 입력한 텍스트: \(searchText)")
        searchWord = searchText
        if searchText == "" {
            fetchTrendingResults()
        } else {
            updateSearchResults()
        }

    }
    
    func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
        print("사용자가 엔터 키를 눌렀습니다.")
        searchBar.resignFirstResponder()
        if let keyword = searchBar.text {
            searchList.append(keyword)
            searchWord = keyword
            addLastSearch()
        }
        resultView.removeFromSuperview()
        haveLastSearchList()
        lastSearchedCollectionView.reloadData()
    }
    
    func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
        fetchTrendingResults()
        searchBar.text = ""
    }
}

참고한 문서
https://sueaty.tistory.com/164
https://fomaios.tistory.com/entry/%EC%84%9C%EC%B9%98%EB%B0%94-%EC%BB%A4%EC%8A%A4%ED%85%80%ED%95%98%EA%B8%B0-Custom-UISearchBar
https://sangnam2.tistory.com/entry/Xcode-%EC%8B%9C%EB%AE%AC%EB%A0%88%EC%9D%B4%ED%84%B0-%EC%B6%94%EA%B0%80-iOS-%EB%B2%84%EC%A0%84-%EC%84%A0%ED%83%9D

profile
🐣 iOS Developer

0개의 댓글