Closed EmmaVvv closed 5 years ago
I need to display nearby objects with their custom icons on the map https://github.com/yandex/mapkit-ios-demo/blob/master/MapKitDemo/MapObjectsViewController.swift
I need to change the object icon on tap
YMKMapObjectCollection* mapObjects = self.mapView.mapWindow.map.mapObjects;
YMKPlacemarkMapObject *placemark = [mapObjects addPlacemarkWithPoint: ...];
[mapObjects addTapListenerWithTapListener:self];
//or [placemark addTapListenerWithTapListener:self];
- (BOOL)onMapObjectTapWithMapObject:(YMKMapObject *)mapObject point:(YMKPoint *)point
{
if ([mapObject isKindOfClass:[YMKPlacemarkMapObject class]]) {
YMKPlacemarkMapObject *placemark = (YMKPlacemarkMapObject *)mapObject;
[placemark setIconWithImage:self.tappedImage];
}
return YES;
}
open the information window down below... You can use MapObject.userData property.
Please keep in mind, mapkit stores weak reference to listeners, so it is needed to store listener by application.
Here's how I do it:
` class MyViewController: UIViewController, YMKMapObjectTapListener {
func onMapObjectTap(with mapObject: YMKMapObject, point: YMKPoint) -> Bool {
guard let placemark = mapObject as? YMKPlacemarkMapObject else { return false }
print(point.latitude, point.longitude)
return true
}`
override func viewDidLoad() {
super.viewDidLoad()
mapView.mapWindow.map.addTapListener(with: self)
} }`
As it was stated by one of your admins. But I get the following error:
Argument type 'AddressesViewController' does not conform to expected type 'YMKLayersGeoObjectTapListener'
When I add this listener, I'm forced to use this method:
func onObjectTap(with event: YMKGeoObjectTapEvent) -> Bool { return true }
But in this case the func onMapObjectTap(with mapObject: YMKMapObject, point: YMKPoint) -> Bool {
isn't called at all.
What should I do, @eberkovich ?
You need to use YMKMapObjectTapListener not YMKLayersGeoObjectTapListener. YMKMapObjectTapListener - handles tap on user map objects. YMKLayersGeoObjectTapListener - handles tap on objects within map layer.
@eberkovich , yes, I added only YMKMapObjectTapListener to my map objects, and now this delegate method is called, but once in a lifetime :)
Here is the piece of code:
`class AddressesViewController: UIViewController, YMKMapObjectTapListener {
override func viewDidLoad() { super.viewDidLoad() let mapObjects = mapView.mapWindow.map.mapObjects mapObjects.addTapListener(with: self) } `
And the delegate method onMapObjectTap(with mapObject: YMKMapObject, point: YMKPoint) is called randomly, when I tap on object, meanwile I get the following messages in log console:
class AddressesViewController: UIViewController, YMKMapObjectTapListener {
But I don't have any other listeners added. Why is this like that?
And my number 2 question is related to object data.
The
mapObject.userData
is always nil How can I get the object details(name, description, rating, working hours, etc.) in a proper way?
method is called, but once in a lifetime called randomly
I do not quite understand, so it is not called once? And what does it mean randomly?
mapObject.userData is always nil
Could you please explain? You fill userData then read it and it is nil?
Yes, in viewDidLoad() I add placemarks with their lat/long-s to mapObjects and when I want to read the data
onMapObjectTap(with mapObject: YMKMapObject, point: YMKPoint)
the mapObject.userData is nil
Could you show your source code?
can you give me your email address?
Could you please put minimum example here?
This is the whole class
`class AddressesViewController: UIViewController, YMKMapObjectTapListener, YMKLayersGeoObjectTapListener {
func onObjectTap(with event: YMKGeoObjectTapEvent) -> Bool {
return true
}
func onMapObjectTap(with mapObject: YMKMapObject, point: YMKPoint) -> Bool {
guard let placemark = mapObject as? YMKPlacemarkMapObject else { return false }
print(placemark)
print("Something tapped")
print(point.latitude, point.longitude)
return true
}
@IBOutlet weak var mapView: YMKMapView!
let locationManager = CLLocationManager()
var currentLocation: CLLocation!
var lat: CLLocationDegrees?
var long: CLLocationDegrees?
var text: String!
override func viewDidLoad() {
super.viewDidLoad()
if (CLLocationManager.authorizationStatus() == .authorizedAlways) || (CLLocationManager.authorizationStatus() == .authorizedWhenInUse) {
currentLocation = locationManager.location
lat = currentLocation.coordinate.latitude
long = currentLocation.coordinate.longitude
} else {
lat = 55.7558
long = 37.6173
}
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
let mapObjects = mapView.mapWindow.map.mapObjects
let placemark = mapObjects.addPlacemarks(with: [YMKPoint(latitude: lat!, longitude: long!), YMKPoint(latitude: 40.220395, longitude: 44.492963)], image: #imageLiteral(resourceName: "halp-full cap"), style: YMKIconStyle(anchor: CGPoint(x: 0, y: 0) as NSValue, rotationType: YMKRotationType.rotate.rawValue as NSNumber, zIndex: 0, flat: true, visible: true, scale: 1.5, tappableArea: nil))
placemark[0].setIconWith(#imageLiteral(resourceName: "locationPointer"))
mapObjects.addTapListener(with: self)
mapView.mapWindow.map.addTapListener(with: self)
mapView.mapWindow.map.move(
with: YMKCameraPosition.init(target: YMKPoint(latitude: lat!, longitude: long!), zoom: 15, azimuth: 0, tilt: 0),
animationType: YMKAnimation(type: YMKAnimationType.smooth, duration: 5),
cameraCallback: nil)
}
}`
It does not use userData property?
When in onMapObjectTap(with mapObject: YMKMapObject, point: YMKPoint) -> Bool
I put a breakpoint and in logs console pring mapObject.userData, it's nil
You need to put data to userData in advance.
Which method should I use for this? I can't uderstand this part.
userData
extension MyViewController: YMKMapObjectTapListener {
// MARK: - YMKMapObjectTapListener
func onMapObjectTap(with mapObject: YMKMapObject?, point: YMKPoint) -> Bool {
guard let placemark = mapObject as? YMKPlacemarkMapObject { return false }
// here you can do what you want to do with tapped placemark
return true
}
}
Author wrote about YMKMapObject and property from userData. He asked HOW he could configure "userData" this property for use the information when delegate onMapObjectTap work. By the way im intersted in this too.
I need to display nearby objects with their custom icons on the map, and on tap event open the information window down below. Besides, I need to change the object icon on tap. How can I implement this? I can hardly find any tutorial or course regarding YandexMapKit. Any help would be appreciated!