[FAQ] 지도/로컬 API 문의 전 꼭 읽어 주세요.
https://devtalk.kakao.com/t/faq-api/125610
한 화면에서 2개 이상의 지도를 띄울 수도 있나요?
[FAQ] 지도/로컬 API 문의 전 꼭 읽어 주세요.
https://devtalk.kakao.com/t/faq-api/125610
한 화면에서 2개 이상의 지도를 띄울 수도 있나요?
아래처럼 사용했는데 지도가 한개밖에 안나옵니다.
어떻게 해야 여러개를 띄울 수 있나요?
import SwiftUI
import KakaoMapsSDK
struct ContentView: View {
@State var draw1: Bool = false
@State var draw2: Bool = false
var body: some View {
VStack {
KakaoMapView(draw: $draw1, viewName: "1").onAppear(perform: {
self.draw1 = true
}).onDisappear(perform: {
self.draw1 = false
}).frame(maxWidth: .infinity, maxHeight: .infinity)
KakaoMapView(draw: $draw2, viewName: "2").onAppear(perform: {
self.draw2 = true
}).onDisappear(perform: {
self.draw2 = false
}).frame(maxWidth: .infinity, maxHeight: .infinity)
}
}
}
struct KakaoMapView: UIViewRepresentable {
@Binding var draw: Bool
var viewName: String
/// UIView를 상속한 KMViewContainer를 생성한다.
/// 뷰 생성과 함께 KMControllerDelegate를 구현한 Coordinator를 생성하고, 엔진을 생성 및 초기화한다.
func makeUIView(context: Self.Context) -> KMViewContainer {
let view: KMViewContainer = KMViewContainer()
view.sizeToFit()
context.coordinator.createController(view)
context.coordinator.controller?.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 {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
context.coordinator.controller?.startEngine()
context.coordinator.controller?.startRendering()
}
}
else {
context.coordinator.controller?.stopRendering()
context.coordinator.controller?.stopEngine()
}
}
/// Coordinator 생성
func makeCoordinator() -> KakaoMapCoordinator {
return KakaoMapCoordinator(viewName: viewName)
}
/// 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 {
init(viewName: String) {
first = true
self.viewName = viewName
super.init()
}
// KMController 객체 생성 및 event delegate 지정
func createController(_ view: KMViewContainer) {
controller = KMController(viewContainer: view)
controller?.delegate = self
}
// KMControllerDelegate Protocol method구현
/// 엔진 생성 및 초기화 이후, 렌더링 준비가 완료되면 아래 addViews를 호출한다.
/// 원하는 뷰를 생성한다.
func addViews() {
let defaultPosition: MapPoint = MapPoint(longitude: 127.108678, latitude: 37.402001)
let mapviewInfo: MapviewInfo = MapviewInfo(viewName: viewName, viewInfoName: "map", defaultPosition: defaultPosition)
if controller?.addView(mapviewInfo) == Result.OK {
let _ = controller?.getView(viewName) as! KakaoMap
}
}
/// KMViewContainer 리사이징 될 때 호출.
func containerDidResized(_ size: CGSize) {
let mapView: KakaoMap? = controller?.getView(viewName) as? KakaoMap
mapView?.viewRect = CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: size)
if first {
let cameraUpdate: CameraUpdate = CameraUpdate.make(target: MapPoint(longitude: 127.108678, latitude: 37.402001), zoomLevel: 10, mapView: mapView!)
mapView?.moveCamera(cameraUpdate)
first = false
}
}
var controller: KMController?
var first: Bool
var viewName: String
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
@JerryKhw 스샷과 같이 하나의 뷰 안에 지도를 복수개 띄워야 하는 경우에는 MapControllerDelegate.addViews 에서 addView를 여러 개 하는 방식으로 사용하시면 됩니다.
KMViewContainer를 두 개 이상 사용하는 경우는 KMController도 각각 개별적으로 생성하여 KMViewContainer에 연결해야 합니다.
그것도 가능한 방법일 수는 있습니다. 샘플의 KakaoMapView는 UIView 로 제공된 KMViewContainer를 SwiftUI 에서 띄우기 위해 구성된 것입니다. 중요한 점은 KMViewContainer와 KMController는 쌍으로 생성해서 사용해야 한다는 것입니다.
(KMViewContainer, KMController) 쌍을 여러 개 만들어서 사용하시거나, 하나의 KMViewContainer 안에서 KMController.addView 여러 개 해서 지도 여러 개를 띄울 수 있습니다.
@vectordev
쌍으로 여러개 만들어서 사용하면 된다고 하셨는데 KMController 의 initEngine() 사용 시 기존 사용중인 엔진을 비활성화 시키는 것 같은데 어떻게 사용해야되는건가요?
시뮬레이터에서 동작하는 OpenGL 모드의 경우 GL 오동작을 막기 위해 엔진 두개가 동시에 동작하지 못하도록 하고 있습니다. 디바이스에서는 Metal로 동작하고 Metal 모드에서는 이러한 제약이 없습니다.
@jjj1211 v2 SDK는 기본적으로 하나의 엔진이 동작하는 상황에 맞춰 설계되었습니다. 동시에 복수개의 엔진이 실행(렌더링) 되는 상황에서 동작은 될 수 있으나 그러한 환경에서 모든 상황에 문제 없이 동작하는 것을 보장하지 않습니다.
해당 사항은 Android/iOS 모두에 해당됩니다.