지도 필터 검색

Judy·2021년 9월 30일
0

지도 화면엔 모든 장소의 마커가 나온다.

기능 자체가 단순하기도 하고 장소 15개 정도로만 테스트해도 너무 밀집해보이고 겹처보이는 마커들이 보였다.

필터 넣는 방법


아이디어1 - 색상을 다르게

마커들을 그룹이나 분류에 따라 색상을 다르게 하면 구분이 쉬워 훨씬 보기 편할 것 같았다.

하지만 색상으로 구분해도 마커가 많아지면 겹치고 복잡해 보이는 건 똑같고, 그룹과 분류 두 가지 기준을 적용하기 어려웠다.

게다가 그룹과 분류의 개수가 정해져있지 않기 때문에 어떤 색상을 적용해야할지 임의로 선택하기 어렵고 다양한 색상이 마커에 적용되지도 않았다.

아이디어2 - 조건으로 검색 ✔️

너무 많이 있는게 문제라면 특정 조건에 해당하는 장소들의 마커만 보여주면 찾기 쉽고 편리하겠단 생각이 들었다.

전체 - 그룹별 - 분류별

이렇게 세 가지로 구분해서 메인 화면처럼 segmented control로 적용할까 싶었지만 더 다양하고 상세하게 조건을 넣고 싶었다.

ex) 그룹1 이면서 분류2인 장소들

특정 분류이면서 특정 그룹에 해당하는 장소를 표시 할 수 있도록 분류와 그룹 동시에 조건을 적용할 수 있어야 했다.



Multiple Columns UIPicker

그룹과 분류 두 가지 조건을 정할 수 있도록 2개의 컬럼을 가진 Picker를 사용했다.

UIPikcer 설정

func numberOfComponents(in pickerView: UIPickerView) -> Int {
    return 2
}
    
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
    if component == 0 {
        return groupList.count
    }else{
        return categoryList.count
    }
}

func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
    if component == 0 {
        return groupList[row]
    }else{
        return categoryList[row]
    }
}

첫 번째 component엔 그룹 목록을, 두 번째 component엔 분류 목록을 넣었다.

각 목록의 첫 번째 항목에 '전체'를 넣어 모든 그룹(분류)일 때를 포함할 수 있게 했다.

Picker로 조건 선택

func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
    let selectedGroup = pickerView.selectedRow(inComponent: 0)
    let selectedCategory = pickerView.selectedRow(inComponent: 1)
        
    if selectedGroup != 0 && selectedCategory != 0{
        optionedPlaces = places.filter{$0.group == groupList[selectedGroup] && $0.category == categoryList[selectedCategory]}
    }else if selectedGroup != 0{
        optionedPlaces = places.filter{$0.group == groupList[selectedGroup]}
    }else if selectedCategory != 0{
        optionedPlaces = places.filter{$0.category == categoryList[selectedCategory]}
    }else{
        optionedPlaces = places
    }
}

각 조건에 따라 filter로 장소를 선별하고 다시 마커를 그리게 했다.

조건

  1. 둘 다 조건 --> 둘 다 조건 필터
  2. 하나는 '전체' + 하나는 조건 --> 조건인 것만 필터
  3. 모두 '전체' --> 필터 없이 원래대로

inputAccessoryView


picker를 어떻게 표시할까 하다 장소 추가에서 사용했던 inputAccessoryView 방식을 재사용하기로 했다.

inputAccessoryView 설정

func setOptionSearchPicker(){
        let pickerToolbar = UIToolbar()
        let btnPickerDone = UIBarButtonItem()
        let flexSpace = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)

        optionPicker.backgroundColor = UIColor.white
        optionPicker.frame = CGRect(x: 0, y: 0, width: 0, height: 200)
        pickerToolbar.frame = CGRect(x: 0, y: 0, width: 0, height: 40)
        pickerToolbar.barTintColor = UIColor.white
        optionTxtf.inputAccessoryView = pickerToolbar
        
        btnPickerDone.title = "검색"
        btnPickerDone.tintColor = #colorLiteral(red: 0, green: 0.8924261928, blue: 0.8863361478, alpha: 1)
        btnPickerDone.target = self
        btnPickerDone.action = #selector(pickerDone)
         
        pickerToolbar.setItems([flexSpace, btnPickerDone], animated: true)
         
        optionPicker.delegate = self
        optionTxtf.inputView = optionPicker
        optionPicker.reloadAllComponents()
    }

firebase에서 목록들을 다운받은 후 바로 picker에 적용이 안 되기 때문에 reload를 해줘야 했다.

 optionPicker.reloadAllComponents()

조건 선택 함수

@objc func pickerDone(){
    mapView?.clear()
    mark(optionedPlaces)
    self.view.endEditing(true)
}

조건을 선택하면 모든 마커를 지우고 조건에 맞게 선별된 장소 목록인 optionedPlaces로 다시 마커를 그리게 했다.

원래는 항상 places로 마커를 그렸기 때문에 mark 함수에는 파라미터가 없었는데 같이 사용하기 위해 [PlaceData] 파라미터를 넣어주었다.




참고 : developer | pickerView

profile
iOS Developer

0개의 댓글