Render LiveLocations in the map (#5394)

This commit is contained in:
Mauro
2026-04-14 18:27:34 +02:00
committed by GitHub
parent a40fab5f5e
commit 602d779e3a
19 changed files with 380 additions and 163 deletions
@@ -6,32 +6,24 @@
// Please see LICENSE files in the repository root for full details.
//
import CoreLocation
import Foundation
import MapLibre
import SwiftUI
final class LocationAnnotation: NSObject, MLNAnnotation {
final class LocationAnnotation: NSObject, MLNAnnotation, Identifiable {
let id: String
var coordinate: CLLocationCoordinate2D
let anchorPoint: CGPoint
var view: AnyView
var kind: LocationMarkerKind
// MARK: - Setup
init(id: String = UUID().uuidString,
coordinate: CLLocationCoordinate2D,
anchorPoint: CGPoint = .init(x: 0.5, y: 0.5),
@ViewBuilder label: () -> some View) {
init(id: String, coordinate: CLLocationCoordinate2D, kind: LocationMarkerKind) {
self.id = id
self.coordinate = coordinate
self.anchorPoint = anchorPoint
view = AnyView(label())
self.kind = kind
super.init()
}
func updateView(@ViewBuilder label: () -> some View) {
view = AnyView(label())
}
}
final class LocationAnnotationView: MLNUserLocationAnnotationView {
@@ -44,19 +36,21 @@ final class LocationAnnotationView: MLNUserLocationAnnotationView {
reuseIdentifier)
}
convenience init(annotation: LocationAnnotation) {
convenience init(annotation: LocationAnnotation, mediaProvider: MediaProviderProtocol?) {
self.init(annotation: annotation, reuseIdentifier: "\(Self.self)")
let hostingController = UIHostingController(rootView: annotation.view)
let markerView = LocationMarkerView(kind: annotation.kind, mediaProvider: mediaProvider)
let hostingController = UIHostingController(rootView: AnyView(markerView))
self.hostingController = hostingController
let view: UIView = hostingController.view
view.backgroundColor = .clear
view.anchorPoint = annotation.anchorPoint
view.anchorPoint = .init(x: 0.5, y: 1.0)
addSubview(view)
view.bounds.size = view.intrinsicContentSize
}
func updateContent(with view: AnyView) {
hostingController?.rootView = view
func updateContent(with kind: LocationMarkerKind, mediaProvider: MediaProviderProtocol?) {
let markerView = LocationMarkerView(kind: kind, mediaProvider: mediaProvider)
hostingController?.rootView = AnyView(markerView)
if let hostedView = hostingController?.view {
hostedView.bounds.size = hostedView.intrinsicContentSize
}