Ios sdk v2에서 다중마커를 표시하는 방법에 관한 예시는 어디서 볼 수 있나요?

[FAQ] 지도/로컬 API 문의 전 꼭 읽어 주세요.
https://devtalk.kakao.com/t/faq-api/125610

리스트에 있는 모든 장소에 poi를 생성하고 싶은데, 다중마커에 대한 예시코드가 있을까요? 찾아봐도 웹용 밖에 못찾겠어서요…

@_1038 다중마커가 어떤 기능을 말씀하시는걸까요?

3개의 장소 리스트가 있고, 각 장소리스트의 레이어를 분리해서, 장소타입 선택시 해당 리스트들의 장소에 모두 poi가 찍히는 코드를 작성중입니다. 리스트 내 모든 장소에 Poi가 찍히는 게 하는 것까지는 해결했는데, 모든 Label Layer가 한번에 같이 나오고 클릭이벤트 시 계속 반복해서 생성되는데, 한꺼번에 Layer자체를 숨기거나 제거하는 건 어떻게 해야 할지 모르겠습니다.
또, 동일 Layer가 계속 재생성되는 문제는 어떻게 해결해야할까요??

아래는 제가 작성중인 코드입니다.

struct KakaoMapView: UIViewRepresentable {
  @Binding var draw: Bool
  @Binding var targetLocation: CLLocationCoordinate2D
  var places: [Store]
  var label: String
  
  /// UIView를 상속한 KMViewContainer를 생성한다.
  /// 뷰 생성과 함께 KMControllerDelegate를 구현한 Coordinator를 생성하고, 엔진을 생성 및 초기화한다.
  func makeUIView(context: Self.Context) -> KMViewContainer {
    let view: KMViewContainer = KMViewContainer()
    view.sizeToFit()
    context.coordinator.createController(view)
    context.coordinator.mapController?.initEngine()
    return view
  }
  
  
  /// Updates the presented `UIView` (and coordinator) to the latest
  /// configuration.
  /// draw가 true로 설정되면 엔진을 시작하고 렌더링을 시작한다.
  /// draw가 false로 설정되면 렌더링을 멈추고 엔진을 stop한다.
  func updateUIView(_ uiView: KMViewContainer, context: Self.Context) {
    if draw {
      context.coordinator.mapController?.startEngine()
      context.coordinator.mapController?.startRendering()
      
      // Label Layer와 Poi Style 생성
      context.coordinator.createLabelLayer()
      context.coordinator.createPoiStyle()
      //Optional("PoiLayer") already exists.
      // 기존의 POI 레이어를 제거하고 새로운 레이어를 생성해야함.
      
    }
    else {
      context.coordinator.mapController?.stopRendering()
      context.coordinator.mapController?.stopEngine()
    }
    
    if targetLocation.latitude != 0.0 && targetLocation.longitude != 0.0 {
        context.coordinator.moveCamera(longitude: targetLocation.longitude, latitude: targetLocation.latitude, zoomLevel: 6)
        for place in places {
            switch place.store_type {
            case "Recent":
              context.coordinator.createPois(longitude: place.location.longitude, latitude: place.location.latitude, label: "", layerID: "RecentLayer")
            case "type2":
              context.coordinator.createPois(longitude: place.location.longitude, latitude: place.location.latitude, label: "", layerID: "type2Layer")
            case "type3":
                context.coordinator.createPois(longitude: place.location.longitude, latitude: place.location.latitude, label: "", layerID: "type3Layer")
            default:
                break
            }
        }
    }
  }
  
  /// Coordinator 생성
  func makeCoordinator() -> KakaoMapCoordinator {
    return KakaoMapCoordinator()
  }
  
  /// Cleans up the presented `UIView` (and coordinator) in
  /// anticipation of their removal.
  static func dismantleUIView(_ uiView: KMViewContainer, coordinator: KakaoMapCoordinator) {
    
  }
  
  /// Coordinator 구현. KMControllerDelegate를 adopt한다.
  class KakaoMapCoordinator: NSObject, MapControllerDelegate, CLLocationManagerDelegate {
    var mapController: KMController?
    var first: Bool
    let locationManager = CLLocationManager()
    
    // SimplePOI class methods
    var poiStyle: PoiStyle?
    
    override init() {
      first = true
      super.init()
      locationManager.delegate = self
      locationManager.desiredAccuracy = kCLLocationAccuracyBest
      locationManager.requestWhenInUseAuthorization()
      locationManager.startUpdatingLocation()
    }
    
    // KMController 객체 생성 및 event delegate 지정
    func createController(_ view: KMViewContainer) {
      mapController = KMController(viewContainer: view)
      mapController?.delegate = self
    }
    
    // KMControllerDelegate Protocol method구현
    
    /// 엔진 생성 및 초기화 이후, 렌더링 준비가 완료되면 아래 addViews를 호출한다.
    /// 원하는 뷰를 생성한다.
    @objc func addViews() {
      if let userLocation = locationManager.location?.coordinate {
        //print("userLocation  Longitude: \(userLocation.longitude), Latitude: \(userLocation.latitude)")
        let defaultPosition: MapPoint = MapPoint(longitude: userLocation.longitude, latitude: userLocation.latitude)
        let mapviewInfo: MapviewInfo = MapviewInfo(viewName: "mapview", viewInfoName: "map", defaultPosition: defaultPosition)
        
        mapController?.addView(mapviewInfo)
        
      }
    }
    //addView 성공 이벤트 delegate. 추가적으로 수행할 작업을 진행한다.
    func addViewSucceeded(_ viewName: String, viewInfoName: String) {
      //print("OK") //추가 성공. 성공시 추가적으로 수행할 작업을 진행한다.
    }
    
    //addView 실패 이벤트 delegate. 실패에 대한 오류 처리를 진행한다.
    func addViewFailed(_ viewName: String, viewInfoName: String) {
      //print("Failed")
    }
    
    /// KMViewContainer 리사이징 될 때 호출.
    func containerDidResized(_ size: CGSize) {
      let mapView: KakaoMap? = mapController?.getView("mapview") as? KakaoMap
      mapView?.viewRect = CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: size)
      if first, let userLocation = locationManager.location?.coordinate {
        let cameraUpdate: CameraUpdate = CameraUpdate.make(target: MapPoint(longitude: userLocation.longitude, latitude: userLocation.latitude), zoomLevel: 6, mapView: mapView!)
        mapView?.moveCamera(cameraUpdate)
        first = false
      }
    }
    
    func moveCamera(longitude: Double, latitude: Double, zoomLevel: Float) {
      guard let mapView = mapController?.getView("mapview") as? KakaoMap else {
        //print("Failed to get KakaoMap view.")
        return
      }
      
      // CameraUpdateType을 CameraPosition으로 생성하여 지도의 카메라를 특정 좌표로 이동시킨다. MapPoint, 카메라가 바라보는 높이, 회전각 및 틸트를 지정할 수 있다.
      mapView.moveCamera(CameraUpdate.make(target: MapPoint(longitude: longitude, latitude: latitude), zoomLevel: 18, mapView: mapView))
      
    }
    
    // POI가 속할 LabelLayer를 생성한다.
    func createLabelLayer() {
      guard let mapView = mapController?.getView("mapview") as? KakaoMap else {
        //print("Failed to get KakaoMap view.")
        return
      }
      
      let labelManager = mapView.getLabelManager()   //LabelManager를 가져온다. LabelLayer는 LabelManger를 통해 추가할 수 있다.
      
//      let layerOption = LabelLayerOptions(layerID: "PoiLayer", competitionType: .none, competitionUnit: .poi, orderType: .rank, zOrder: 10001)
//      let _ = labelManager.addLabelLayer(option: layerOption)
      
      // RecentLayer 생성
      let recentLayerOption = LabelLayerOptions(layerID: "RecentLayer", competitionType: .none, competitionUnit: .poi, orderType: .rank, zOrder: 10001)
      let _ = labelManager.addLabelLayer(option: recentLayerOption)
      
      // type2Layer 생성
      let type2LayerOption = LabelLayerOptions(layerID: "type2Layer", competitionType: .none, competitionUnit: .poi, orderType: .rank, zOrder: 10002)
      let _ = labelManager.addLabelLayer(option: type2LayerOption)
      
      // type3Layer 생성
      let type3LayerOption = LabelLayerOptions(layerID: "type3Layer", competitionType: .none, competitionUnit: .poi, orderType: .rank, zOrder: 10003)
      let _ = labelManager.addLabelLayer(option: type3LayerOption)
      
      //print("createLabelLayer")
    }
    
    func createPoiStyle() {
      guard let mapView = mapController?.getView("mapview") as? KakaoMap else {
        //print("Failed to get KakaoMap view.")
        return
      }
      let labelManager = mapView.getLabelManager()
      
      // 심볼을 지정.
      // 심볼의 anchor point(심볼이 배치될때의 위치 기준점)를 지정. 심볼의 좌상단을 기준으로 한 % 값.
      let iconStyle = PoiIconStyle(symbol: UIImage(named: "ic_position_pin_shadow"), anchorPoint: CGPoint(x: 0.5, y: 0.8))
      
      // text Style 지정
      var textLineStyles = [PoiTextLineStyle]()
      let text = TextStyle(fontSize: 25, fontColor: UIColor.black, strokeThickness: 3, strokeColor: UIColor.white)
      
      let textLineStyle = PoiTextLineStyle(textStyle: text)
      textLineStyles.append(textLineStyle)
      
      let textStyle = PoiTextStyle(textLineStyles: textLineStyles)
      textStyle.textLayouts = [.bottom]
      
      let perLevelStyle = PerLevelPoiStyle(iconStyle: iconStyle, textStyle: textStyle, level: 0)  // 이 스타일이 적용되기 시작할 레벨.
      let poiStyle = PoiStyle(styleID: "customStyle1", styles: [perLevelStyle])
      labelManager.addPoiStyle(poiStyle)
      //print("createPoiStyle")
      //print(iconStyle)
    }
    
    // POI를 생성한다.
    func createPois(longitude: Double, latitude: Double, label: String, layerID: String) {
        guard let mapView = mapController?.getView("mapview") as? KakaoMap else {
            return
        }
        let labelManager = mapView.getLabelManager()
        let layer = labelManager.getLabelLayer(layerID: layerID)   // 생성한 POI를 추가할 레이어를 가져온다.
        let poiOption = PoiOptions(styleID: "customStyle1") // 생성할 POI의 Option을 지정하기 위한 자료를 담는 클래스를 생성. 사용할 스타일의 ID를 지정한다.
        poiOption.rank = 0
        poiOption.addText(PoiText(text: label, styleIndex: 0)) // PoiTextLineStyle[0] 적용

        let poi1 = layer?.addPoi(option: poiOption, at: MapPoint(longitude:longitude, latitude: latitude), callback: {(_ poi: (Poi?)) -> Void in
        })
        poi1?.show()
    }
    
  }
}

@_1038
우선 POI 생성 관련 코드를 다른 곳으로 옮기시는 것이 맞습니다. 지금 올려주신 코드상의 위치는 적절하지 않습니다.
updateUIView 함수는 view 상태 업데이트가 됨에 따라 반복적으로 호출될 수 있습니다. 이에 대한 자세한 내용은 애플 공식문서( updateUIView(_:context:) | Apple Developer Documentation) 나 관련 자료를 참고 하시기 바랍니다.
LabelLayer에는 layer의 visible 속성을 지정할 수 있으며, layer에 속한 label 들을 개별 혹은 모두 숨기거나 삭제할 수 있습니다. 이에 대한 부분은 API 문서를 참고하시기 바랍니다.

visible 속성은 어떻게 지정하나요?

@_1038

layer.visible = false

하시면 됩니다.