Skip to content

Instantly share code, notes, and snippets.

@stakancheck
Last active January 23, 2024 17:40
Show Gist options
  • Save stakancheck/1daef28a83c76039b6d661b544a10d36 to your computer and use it in GitHub Desktop.
Save stakancheck/1daef28a83c76039b6d661b544a10d36 to your computer and use it in GitHub Desktop.
MapViewController.swift (iosApp)
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