Last active
January 23, 2024 17:40
-
-
Save stakancheck/1daef28a83c76039b6d661b544a10d36 to your computer and use it in GitHub Desktop.
MapViewController.swift (iosApp)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Foundation | |
import YandexMapsMobile | |
import ComposeApp | |
import UIKit | |
class MapViewController: UIViewController { | |
private let locationMark: UIImage = UIImage(named: "location_mark")! | |
private let myLocatioPoint: UIImage = UIImage(named: "my_location_point")! | |
override func viewDidLoad() { | |
super.viewDidLoad() | |
mapView = YMKMapView(frame: view.frame) | |
YMKMapKit.sharedInstance().onStart() | |
view.addSubview(mapView) | |
map = mapView.mapWindow.map | |
addMyLocationPlacemark() | |
addCustomLocationPlacemark() | |
map.addCameraListener(with: mapCameraListener) | |
map.addInputListener(with: mapInputListener) | |
pinsCollection = map.mapObjects.add() | |
} | |
private func move(to cameraPosition: YMKCameraPosition) { | |
map.move(with: cameraPosition, animation: YMKAnimation(type: .smooth, duration: 0.2)) | |
} | |
private func addMyLocationPlacemark() { | |
myPointPlacemark = map.mapObjects.addPlacemark() | |
myPointPlacemark.setIconWith( | |
myLocatioPoint, | |
style: { | |
let iconStyle = YMKIconStyle() | |
iconStyle.anchor = NSValue(cgPoint: CGPoint(x: 0.5, y: 0.5)) | |
iconStyle.scale = 0.14 | |
iconStyle.flat = true | |
return iconStyle | |
}() | |
) | |
} | |
private func addCustomLocationPlacemark() { | |
customPointPlacemark = map.mapObjects.addPlacemark() | |
customPointPlacemark.setIconWith( | |
locationMark, | |
style: { | |
let iconStyle = YMKIconStyle() | |
iconStyle.anchor = NSValue(cgPoint: CGPoint(x: 0.5, y: 1)) | |
iconStyle.scale = 0.14 | |
iconStyle.flat = false | |
return iconStyle | |
}() | |
) | |
} | |
private var mapView: YMKMapView! | |
private var map: YMKMap! | |
private var myPointPlacemark: YMKPlacemarkMapObject! | |
private var customPointPlacemark: YMKPlacemarkMapObject! | |
private var pinsCollection: YMKMapObjectCollection! | |
private lazy var mapCameraListener: MapCameraListener = MapCameraListener() | |
private lazy var mapInputListener: MapInputListener = MapInputListener() | |
private lazy var mapPointListener: MapPointListener = MapPointListener(controller: self) | |
func addCameraListener(onDragged: @escaping () -> Void) { | |
mapCameraListener.onDragged = onDragged | |
} | |
func addInputListener(onPositionSelect: @escaping (_ latitude: Double, _ longitude: Double) -> Void = {_, _ in }) { | |
mapInputListener.onPositionSelect = onPositionSelect | |
} | |
func addPointListener(onPointClick: @escaping (KotlinLong) -> Void) { | |
mapPointListener.onPointClick = { id, latLng in | |
self.mapMove(latLng: latLng) | |
onPointClick(id) | |
} | |
} | |
func startMap() { | |
YMKMapKit.sharedInstance().onStart() | |
} | |
func stopMap() { | |
YMKMapKit.sharedInstance().onStop() | |
} | |
func mapMove(latLng: LatLng) { | |
move(to: YMKCameraPosition(target: YMKPoint(latitude: latLng.latitude, longitude: latLng.longitude), zoom: 16.0, azimuth: 0.0, tilt: 0.0)) | |
} | |
func updateMyPoint(latLng: LatLng?, visible: Bool) { | |
if myPointPlacemark != nil { | |
if latLng != nil { | |
myPointPlacemark.geometry = YMKPoint(latitude: latLng!.latitude, longitude: latLng!.longitude) | |
} | |
myPointPlacemark.isVisible = visible | |
} | |
} | |
func updateCustomPoint(latLng: LatLng?, visible: Bool) { | |
if customPointPlacemark != nil { | |
if latLng != nil { | |
customPointPlacemark.geometry = YMKPoint(latitude: latLng!.latitude, longitude: latLng!.longitude) | |
} | |
customPointPlacemark.isVisible = visible | |
} | |
} | |
func updateFocusArea(bottomFocusAreaPadding: Int) { | |
let yVal = Float(mapView.mapWindow.height() - (bottomFocusAreaPadding as Int)) | |
mapView.mapWindow.focusRect = YMKScreenRect( | |
topLeft: YMKScreenPoint(x: 0, y: 0), | |
bottomRight: YMKScreenPoint( | |
x: Float(mapView.mapWindow.width()), | |
y: yVal < 0 ? 0 : yVal | |
) | |
) | |
} | |
func updatePointsCollection(points: [PointMapModel]) { | |
pinsCollection.clear() | |
if pinsCollection != nil { | |
points.forEach { point in | |
let pin = pinsCollection.addPlacemark() | |
pin.geometry = YMKPoint(latitude: point.latLng.latitude, longitude: point.latLng.longitude) | |
pin.setIconWith( | |
locationMark, | |
style: { | |
let iconStyle = YMKIconStyle() | |
iconStyle.anchor = NSValue(cgPoint: CGPoint(x: 0.5, y: 1)) | |
iconStyle.scale = 0.14 | |
iconStyle.flat = false | |
return iconStyle | |
}() | |
) | |
pin.setTextWithText( | |
point.name, | |
style: { | |
let textStyle = YMKTextStyle() | |
textStyle.size = 10 | |
textStyle.placement = YMKTextStylePlacement.right | |
textStyle.offset = 5 | |
return textStyle | |
}() | |
) | |
pin.userData = PointUserData(id: point.id) | |
pin.addTapListener(with: mapPointListener) | |
} | |
} | |
} | |
final private class MapInputListener: NSObject, YMKMapInputListener { | |
var onPositionSelect: (_ latitude: Double, _ longitude: Double) -> Void | |
init(onPositionSelect: @escaping (_ latitude: Double, _ longitude: Double) -> Void = {_, _ in }) { | |
self.onPositionSelect = onPositionSelect | |
} | |
func onMapTap(with map: YMKMap, point: YMKPoint) { | |
onPositionSelect(point.latitude, point.longitude) | |
} | |
func onMapLongTap(with map: YMKMap, point: YMKPoint) {} | |
} | |
final private class MapCameraListener: NSObject, YMKMapCameraListener { | |
var onDragged: () -> Void | |
init(onDragged: @escaping () -> Void = {}) { | |
self.onDragged = onDragged | |
} | |
func onCameraPositionChanged(with map: YMKMap, cameraPosition: YMKCameraPosition, cameraUpdateReason: YMKCameraUpdateReason, finished: Bool) { | |
if (cameraUpdateReason == YMKCameraUpdateReason.gestures) { | |
onDragged() | |
} | |
} | |
} | |
final private class MapPointListener: NSObject, YMKMapObjectTapListener { | |
var onPointClick: (KotlinLong, LatLng) -> Void | |
init(controller: UIViewController, onPointClick: @escaping (KotlinLong, LatLng) -> Void = {_, _ in}) { | |
self.controller = controller | |
self.onPointClick = onPointClick | |
} | |
func onMapObjectTap(with mapObject: YMKMapObject, point: YMKPoint) -> Bool { | |
let userData = mapObject.userData as! PointUserData | |
onPointClick(KotlinLong(value: userData.id), LatLng(latitude: point.latitude, longitude: point.longitude)) | |
return true | |
} | |
private weak var controller: UIViewController? | |
} | |
private struct PointUserData { | |
let id: Int64 | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment