Save map annotation using UserDefaults - swift

I have been searching relentlessly for this solution and left with no choice except to rely on the expertise here on Stackoverflow. I am working on saving a map annotation if the app closes and I have been using the UserDefault to save the annotation.
This is the Objective C code that I found and I tried converting it into Swift and I think there is an error with it. I am not too sure. I place this code at viewDidLoad()
This is the save annotation
var pinnedAnnotation: CLLocationCoordinate2D = (parkedCarAnnotation?.coordinate)!
var coordinateData: NSData = NSData(bytesNoCopy: pinnedAnnotation, length: sizeof(pinnedAnnotation), freeWhenDone: false)
UserDefaults.standard.set(coordinateData, forKey: pinnedAnnotation)
UserDefaults.standard.synchronize()
And I needed a load annotation when the app open.
I dont know if viewDidLoad is the right place to put. Previously I put it in a mapView function of updatingLocation
Edited: Added code for further clarification of what I have done that needed to be corrected
override func viewDidLoad() {
super.viewDidLoad()
mapView.delegate = self as MKMapViewDelegate
checkLocationAuthorizationStatus()
tabBar.delegate = self
if UserDefaults.standard.object(forKey: "pinnedAnnotation") != nil {
let annotation = MKPointAnnotation()
self.mapView.addAnnotation(annotation)
}
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let pinnedAnnotation: CLLocationCoordinate2D = (parkedCarAnnotation?.coordinate)!
let locationData = ["latitude": parkedCarAnnotation?.coordinate.latitude, "longitude": parkedCarAnnotation?.coordinate.longitude]
UserDefaults.standard.set(locationData, forKey: "pinnedAnnotation")
UserDefaults.standard.synchronize()
print("Saving data ", UserDefaults.standard.set(locationData, forKey: "pinnedAnnotation"))
}
func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) {
if(item.tag == 0){
if mapView.annotations.count == 1{
mapView.addAnnotation(parkedCarAnnotation!)
} else {
mapView.removeAnnotation(mapView.annotations as! MKAnnotation)
}
}
extension ViewController: MKMapViewDelegate {
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
if let annotation = annotation as? ParkingSpot{
let identifier = "pin"
var view: MKPinAnnotationView
view = MKPinAnnotationView(annotation: annotation, reuseIdentifier: identifier)
view.canShowCallout = true
view.animatesDrop = true
view.pinTintColor = UIColor.orange
view.calloutOffset = CGPoint(x: -8, y: -3)
view.rightCalloutAccessoryView = UIButton.init(type:.detailDisclosure) as UIView
return view
} else {
return nil
}
}
extension ViewController: CLLocationManagerDelegate{
func mapView(_ mapView: MKMapView, didUpdate userLocation: MKUserLocation) {
centerMapOnLocation(location: CLLocation(latitude: userLocation.coordinate.latitude, longitude: userLocation.coordinate.longitude))
let locationServiceCoordinate = LocationService.instance.locationManager.location!.coordinate
parkedCarAnnotation = ParkingSpot(title: "My Parking Spot", locationName: "Find your way back to your car location", coordinate: CLLocationCoordinate2D(latitude: locationServiceCoordinate.latitude, longitude: locationServiceCoordinate.longitude))
}
}

I'm not entirely sure what you're asking...
For starters when you're saving data to UserDefaults the key needs to be a string, I also believe you'll need to save you data in UserDefaults as a Dictionary
let locationData = ["lat": parkedCarAnnotation?.coordinate?.latitude, "long": parkedCarAnnotation?.coordinate.longitude]
UserDefaults.standard.set(locationData, forKey: "pinned_annotation")
And then to retrieve the data you would call
if let annotationData = UserDefaults.standard.object(forKey: "pinned_annotation") as? Dictionary {
guard let lat = annotationData["lat"], let long = annotationData["long"] else { return }
let coordinate = CLLocationCoordinate2D(latitude: lat, longitude: long)
}
Now you should hopefully be able to set your annotation with the coordinate

Related

Swift - How to update observed data in a (custom or not) MKAnnotation callout WITHOUT deselecting the annotation

I'm struggling to get KVO updates within a callout already displayed.
My use case: I want to display on an open callout the real time distance between user location and the annotation I add to the map. Annotation does not change its position.
I add annotations to mapView, using a custom annotation I have defined. No issue here.
On each annotation selected, the callout displays all the information defined in the custom annotation
However, the distance is refreshed in the callout ONLY if I unselect the annotation and reselect it
The distance property is declared as #objc dynamic so it can be observed.
I compute the distance each time the user location change. This part works too.
I cannot figure out what I'm missing to have the callout updated without closing and reopening it.
The code I'm using is what is described here by Rob: Swift -How to Update Data in Custom MKAnnotation Callout?
So my question: is it possible to change realtime a value (observed) in a notificationView callout ? If yes is KVO the best approach ?
In the link below, how would be implemented the mapView viewFor method ?
Any example would be very helpful.
It's my first post here, so please if I did it wrong, let me know and I will provide more information and details.
But my situation is trivial: the standard callout performs Key-Value Observation (KVO) on title and subtitle. (And the annotation view observes changes to coordinate.). But how to display change of values in the current open callout ? That is the think I do not get.
CustomAnnotation class:
class CustomAnnotation: NSObject, MKAnnotation {
#objc dynamic var title: String?
#objc dynamic var subtitle: String?
#objc dynamic var coordinate: CLLocationCoordinate2D
#objc dynamic var distance: CLLocationDistance
var poiColor: String?
var poiPhone: String?
init(title: String, subtitle: String, coordinate: CLLocationCoordinate2D, poiColor: String, poiPhone: String, distance: CLLocationDistance) {
self.title = title
self.subtitle = subtitle
self.coordinate = coordinate
self.poiColor = poiColor
self.poiPhone = poiPhone
self.distance = distance
super.init()
}
}
CustomAnnotationView class:
class CustomAnnotationView: MKMarkerAnnotationView {
override init(annotation: MKAnnotation?, reuseIdentifier: String?) {
super.init(annotation: annotation, reuseIdentifier: reuseIdentifier)
displayPriority = .required
canShowCallout = true
detailCalloutAccessoryView = createCallOutWithDataFrom(customAnnotation: annotation as? CustomAnnotation)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
deinit {
removeAnyObservers()
}
override var annotation: MKAnnotation? {
didSet {
removeAnyObservers()
if let customAnnotation = annotation as? CustomAnnotation {
updateAndAddObservers(for: customAnnotation)
}
}
}
private var subtitleObserver: NSKeyValueObservation?
private var distanceObserver: NSKeyValueObservation?
private let subtitleLabel: UILabel = {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
return label
}()
private let distanceLabel: UILabel = {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
return label
}()
}
private extension CustomAnnotationView {
func updateAndAddObservers(for customAnnotation: CustomAnnotation) {
subtitleLabel.text = customAnnotation.subtitle
subtitleObserver = customAnnotation.observe(\.subtitle) { [weak self] customAnnotation, _ in
self?.subtitleLabel.text = customAnnotation.subtitle
}
let locationManager = CLLocationManager()
let theLatitude:CLLocationDegrees = (locationManager.location?.coordinate.latitude)!
let theLongitude:CLLocationDegrees = (locationManager.location?.coordinate.longitude)!
// Get pin location
let pointLocation = CLLocation(latitude: customAnnotation.coordinate.latitude, longitude: customAnnotation.coordinate.longitude)
//Get user location
let userLocation = CLLocation(latitude: theLatitude, longitude: theLongitude)
// Return distance en meters
let distanceFromUser = pointLocation.distance(from: userLocation)
customAnnotation.distance = distanceFromUser*100
distanceLabel.text = String(format: "%.03f", customAnnotation.distance)+" cm"
distanceObserver = customAnnotation.observe(\.distance) { [weak self] customAnnotation, _ in
self?.distanceLabel.text = "\(customAnnotation.distance) cm"
}
}
func removeAnyObservers() {
subtitleObserver = nil
distanceObserver = nil
}
func createCallOutWithDataFrom(customAnnotation: CustomAnnotation?) -> UIView {
let view = UIView()
view.translatesAutoresizingMaskIntoConstraints = true
view.addSubview(subtitleLabel)
view.addSubview(distanceLabel)
NSLayoutConstraint.activate([
subtitleLabel.topAnchor.constraint(equalTo: view.topAnchor),
subtitleLabel.leadingAnchor.constraint(equalTo: view.leadingAnchor),
subtitleLabel.trailingAnchor.constraint(equalTo: view.trailingAnchor),
subtitleLabel.bottomAnchor.constraint(equalTo: distanceLabel.topAnchor),
distanceLabel.leadingAnchor.constraint(equalTo: view.leadingAnchor),
distanceLabel.trailingAnchor.constraint(equalTo: view.trailingAnchor),
distanceLabel.bottomAnchor.constraint(equalTo: view.bottomAnchor)
])
if let customAnnotation = customAnnotation {
updateAndAddObservers(for: customAnnotation)
}
return view
}
}
And to finish:
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
if annotation is MKUserLocation { return nil }
let annotation = annotation as? CustomAnnotation
var annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: "CustomAnnotation") as? CustomAnnotationView
if annotationView == nil {
annotationView = CustomAnnotationView(annotation: annotation, reuseIdentifier: "CustomAnnotation")
annotationView?.canShowCallout = true
} else {
annotationView?.annotation = annotation
}
return annotationView
}
Thank you.
You would appear to have correctly configured the observers for the subtitle and distance. The problem is that a change in location is not triggering an update to distance. Thus, there is nothing triggering the KVO.
You have an observer for distance, which will trigger an update of the label. But you are not changing distance. You should remove the CLLocationManager code from that routine where you add the observers, and instead create a location manager (not within the annotation view, though) which uses its delegate to update all of the annotation distances, e.g.:
class ViewController: UIViewController {
#IBOutlet weak var mapView: MKMapView!
let locationManager = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
locationManager.distanceFilter = 5
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.delegate = self
locationManager.requestWhenInUseAuthorization()
locationManager.startUpdatingLocation()
}
}
extension ViewController: CLLocationManagerDelegate {
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
guard let currentLocation = locations.last(where: { $0.horizontalAccuracy >= 0 }) else { return }
mapView.annotations
.compactMap { $0 as? CustomAnnotation }
.forEach {
$0.distance = CLLocation(latitude: $0.coordinate.latitude, longitude: $0.coordinate.longitude)
.distance(from: currentLocation)
}
}
}
Obviously, you would remove the CLLocationManager code from updateAndAddObservers.

Weird behavior of custom annotations views

I've built the same code in SwiftUI and Storyboard and I get the same weird issues.
Whenever I run and go to background and back to foreground, the custom views are lost.
Whenever I zoom-drag far (say 10km), I also lose the non-picture-holding pin, eg "Pencil".
I'm not sure where I've gone amiss, except maybe that I'd need to separate my pins per annotation view "type" (with a given picture, with text...) and set a different reuse identifier based on that, but it sounds weird given I'm not actually creating anything new (only setting properties of the base MKAnnotationView class).
Using the UIKit version as reference:
import UIKit
import MapKit
class MapViewController: UIViewController {
#IBOutlet weak var mapView: MKMapView!
let cityMapManager = CityMapManager()
let cityMapViewDelegate = CityMapViewDelegate()
let places: [Place] = [Place(name: "Cathedral", location: .init(latitude: 50.640364, longitude: 3.062058))]
override func viewDidLoad() {
super.viewDidLoad()
mapView.setRegion(MKCoordinateRegion(center: CLLocationCoordinate2D(latitude: 50.640364, longitude: 3.062058), latitudinalMeters: 500.0, longitudinalMeters: 500.0), animated: false)
mapView.showsUserLocation = true
mapView.showsScale = true
mapView.delegate = cityMapViewDelegate
annotateLocalPOI(map: mapView)
}
private func annotateLocalPOI(map: MKMapView) {
var annotation = MKPointAnnotation()
annotation.title = "Red Pin"
annotation.subtitle = "I'm a pin and I'm red. Maybe, or not."
annotation.coordinate = CLLocationCoordinate2D(latitude: 50.64, longitude: 3.06)
// add the annotation to the map (will use red pin, mapView:viewFor: allows changing the display)
map.addAnnotation(annotation)
annotation = MKPointAnnotation()
annotation.title = "Pencil"
annotation.subtitle = "Will not display"
annotation.coordinate = CLLocationCoordinate2D(latitude: 50.642, longitude: 3.059)
map.addAnnotation(annotation)
}
}
struct Place: Identifiable {
let id: UUID = UUID()
let name: String
let location: CLLocationCoordinate2D
}
class CityMapViewDelegate: NSObject, MKMapViewDelegate {
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
guard annotation is MKPointAnnotation else { return nil }
let identifier = "Annotation"
var annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: identifier)
if annotationView == nil {
annotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: identifier)
annotationView!.canShowCallout = true
if annotation.title == "Red Pin" {
let pinImage = UIImage(systemName: "timelapse")
annotationView?.image = pinImage
}
if annotation.title == "Pencil" {
// this overrules any subtitle available
annotationView?.detailCalloutAccessoryView = UIImageView(image: UIImage(systemName: "pencil"))
}
} else {
// reset
annotationView?.detailCalloutAccessoryView = nil
annotationView?.image = nil
// set it up again
annotationView?.annotation = annotation
if annotation.title == "Red Pin" {
let pinImage = UIImage(systemName: "timelapse")
annotationView?.image = pinImage
}
if annotation.title == "Pencil" {
// this overrules any subtitle available
annotationView?.detailCalloutAccessoryView = UIImageView(image: UIImage(systemName: "pencil"))
}
}
return annotationView
}
}
class CityLocationManagerDelegate: NSObject, CLLocationManagerDelegate {
var locationStatus = "Status not determined"
var locationFixFound = false
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
// We've (at least once) gone under a certain minimum accuracy required to consider we have a "fix"
// we could use that to reflect that information on the UI (color, shape...)
if !locationFixFound {
for location in locations {
if location.horizontalAccuracy < 25.0 {
locationFixFound = true
}
}
}
}
func locationManager(_ manager: CLLocationManager,
didFailWithError error: Error) {
manager.stopUpdatingLocation()
print("Location manager stopped due to error: \(error)")
}
func locationManager(_ manager: CLLocationManager,
didChangeAuthorization status: CLAuthorizationStatus) {
print("Authorization Status changed")
var shouldRequestLocationUpdates = false
switch status {
case CLAuthorizationStatus.restricted:
locationStatus = "Restricted Access to location"
case CLAuthorizationStatus.denied:
locationStatus = "User denied access to location"
case CLAuthorizationStatus.notDetermined:
locationStatus = "Status not determined"
default:
locationStatus = "Allowed to location Access"
shouldRequestLocationUpdates = true
}
if (shouldRequestLocationUpdates == true) {
NSLog("Location to Allowed")
// Start location services
manager.startUpdatingLocation()
} else {
NSLog("Denied access: \(locationStatus)")
}
}
}
struct CityMapManager {
let locationDelegate: CLLocationManagerDelegate
let locationManager: CLLocationManager
init() {
locationDelegate = CityLocationManagerDelegate()
locationManager = CLLocationManager()
locationManager.delegate = locationDelegate
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestWhenInUseAuthorization()
locationManager.requestAlwaysAuthorization()
}
}
and a storyboard that holds a fullscreen map within a class set to MapViewController.

How to let user to add custom annotation?

I could not found any document, video or stackoverflow answer.
Here is my problem. I created map and add into my custom MKAnnotation and MKAnnotationView.
I want to let user to create custom pin and save to it's local via CoreData
MyCustomAnnotation has same attributes which is title, subtitle, and coordinate.
The first solution that I come up with put a button which creates a draggable pin to user location.
But I need to get less complex, more sophistication solution.
private func addPins() {
let list = PrivateLocations.shared.initLocations()
for pin in list {
map.addAnnotation(pin)
}
}
func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) {
if view.annotation is MKUserLocation { return }
let views = Bundle.main.loadNibNamed("CustomCalloutView", owner: nil, options: nil)
let customView = views?[0] as! CustomCalloutView
customView.delegate = self
customView.isUserInteractionEnabled = true
customView.titleLabel.text = view.annotation?.title!
customView.desc.text = view.annotation?.subtitle!
customView.center = CGPoint(x: view.bounds.size.width / 2, y: -customView.bounds.size.height*0.52)
view.addSubview(customView)
map.setCenter((view.annotation?.coordinate)!, animated: true)
}
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
if annotation is MKUserLocation {
return nil
} else {
let annotationView = MKAnnotationView(annotation: annotation, reuseIdentifier: "CustomAnnotationView")
annotationView.image = UIImage(named: "myImage")
annotationView.canShowCallout = false
return annotationView
}
}
And finally here is my CustomPin class :
var coordinate: CLLocationCoordinate2D
var title: String?
var subtitle: String?
init(_ title: String, _ subtitle: String, _ coordinate: CLLocationCoordinate2D) {
self.title = title
self.subtitle = subtitle
self.coordinate = coordinate
}
That's how I solve this problem,
1) Create a UIView for user show where he wants to add an annotation.
2) Add a pan gesture recognizer in it.
func addPanGesture(view: UIView) {
let pan = UIPanGestureRecognizer(target: self, action: #selector (self.handlePan(sender:)))
view.addGestureRecognizer(pan)
}
3) In my selector func, I call pinDropped() func
#objc func handlePan(sender: UIPanGestureRecognizer) {
let view = sender.view!
let translation = sender.translation(in: self.mapView)
switch sender.state {
case .began, .changed:
pinImage.center = CGPoint(x: dropPinImage.center.x + translation.x, y: dropPinImage.center.y + translation.y)
sender.setTranslation(CGPoint.zero, in: view)
break
default:
pinDropped()
break
}
}
4) I write what will be happening in my pinDropped func
func pinDropped() {
DispatchQueue.main.async {
let pin = CustomPin(self.lastOrigin, "pin")
self.mapView.addAnnotation(pin)
}
self.saveButton.alpha = 1
pinImage.alpha = 0
}

Why the MKPolyline didn't show up in my application?

I am trying to create an application, one of its function is to drawing the line while users are moving.
Here is the class
class traceuserViewController: UIViewController,CLLocationManagerDelegate, MKMapViewDelegate {
var locationManager = CLLocationManager()
var startLocation: CLLocation?
var endLocation: CLLocation?
#IBOutlet weak var mapView: MKMapView!
override func viewDidLoad() {
super.viewDidLoad()
locationManager.delegate = self
self.locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
self.locationManager.distanceFilter = 30.0
self.locationManager.startMonitoringSignificantLocationChanges()
self.locationManager.startUpdatingLocation()
mapView.showsUserLocation = true
mapView.mapType = .hybrid
self.mapView.delegate = self
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
//user's current location
let nowlocation = locations.last
userLocations.append(nowlocation!)
print("HERE IS THE LOCATION ARRAY")
print(userLocations)
//show the current location region
let center = CLLocationCoordinate2D(latitude: nowlocation!.coordinate.latitude, longitude: nowlocation!.coordinate.longitude)
let region = MKCoordinateRegion(center: center, span: MKCoordinateSpan(latitudeDelta: 0.7, longitudeDelta: 0.7))
self.mapView.setRegion(region, animated: true)
drawRoute(locationArray: userLocations)
}
func drawRoute(locationArray: [CLLocation]) {
if (locationArray.count) > 1 {
var destinationLocIndex = (locationArray.count) - 1
var startLocIndex = (locationArray.count) - 2
let destinationloc = locationArray[destinationLocIndex].coordinate
let startLoc = locationArray[startLocIndex].coordinate
var routeArray = [startLoc, destinationloc]
//test if the function works well or not
print(routeArray)
var geodesicLine = MKGeodesicPolyline(coordinates: routeArray , count: routeArray.count)
mapView.add(geodesicLine, level: .aboveRoads)
}
}
//draw in the mapview
private func mapView(mapView: MKMapView, rendererForOverlay overlay: MKOverlay) -> MKOverlayRenderer! {
if overlay is MKPolyline{
let polylineRenderer = MKPolylineRenderer(overlay: overlay)
polylineRenderer.strokeColor = UIColor.blue
polylineRenderer.lineWidth = 5.0
return polylineRenderer
}else{
os_log("Failed to draw the polyline", log: OSLog.default, type: .debug)
return nil
}
}
After many times trying, I still have no idea why it doesn't draw the route on the map when the user is moving, can anyone please I've me some hints?
cheers
I'm inferring that you are using Swift 3 from the code snippet (e.g. the signature of didUpdateLocations; the use of .hybrid rather than Swift 2.3's .Hybrid; etc.).
But, the signature for mapView(_:rendererFor:) is incorrect. In Swift 3, it is:
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
...
}
If you ever have a delegate method that doesn't appear to work, add a breakpoint in it and you can confirm if it's called at all or not (and if it is called, you can step through it and diagnose the problem further).

Swift Custom Annotation does not get select

I have a custom annotationView on my map, when I select the custom annotation i want to create a action and pass the annotation data to another view. The best way for it to work I would have to use the built in func didSelect. When i do select the custom annotation nothing thing happen. Im not show why the didSelect function did not get called thank you in advance.
class RquestCustomPointAnnotation:MKPointAnnotation {
var image: String!
}
func placeRquestByUsersOnMap(){
//retrieve item from firebase
var markerArray = [MKPointAnnotation]()
let path = "rquest/frontEnd/posts/userCreatedPost"
self.childRef(path).observe(.childAdded, andPreviousSiblingKeyWith: {snapshot, _ in
//get status
if let status = snapshot.childSnapshot(forPath: "status").value as? String {
if status == "pending"{
let indentifier = "rquest"
if let coordinate = snapshot.childSnapshot(forPath: "coordinate").value as? NSDictionary {
let lat = coordinate["lat"] as! Double
let long = coordinate["long"] as! Double
let location = CLLocationCoordinate2D(latitude: lat, longitude: long)
let point = RquestCustomPointAnnotation()
let rquestView = MKAnnotationView(annotation: point, reuseIdentifier: indentifier)
point.image = "22"
let key = snapshot.key
point.coordinate = location
point.accessibilityValue = key
point.accessibilityLabel = "Rquest"
markerArray.append(point)
self.mapView.addAnnotation(rquestView.annotation!)
//create an obserarver to check if it is
let paths = "rquest/frontEnd/posts/userCreatedPost/\(key)/"
self.childRef(paths).observe(.childChanged, andPreviousSiblingKeyWith: { (snap, _) in
if snap.key == "status" {
if let status = snap.value as? String {
if status != "pending" {
for i in markerArray {
if i.accessibilityValue == key {
self.mapView.removeAnnotation(i)
}
}
}
}
}
})
}
}
}
})
}
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
if annotation is RquestCustomPointAnnotation {
let reuseIdentifier = "rquest"
var annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: reuseIdentifier)
if annotationView == nil {
annotationView = MKAnnotationView(annotation: annotation, reuseIdentifier: reuseIdentifier)
annotationView?.canShowCallout = true
} else {
annotationView?.annotation = annotation
}
let customPointAnnotation = annotation as! RquestCustomPointAnnotation
annotationView?.image = UIImage(named: customPointAnnotation.image)
return annotationView
}
}
func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) {
print("did select")
}
You have canShowCallout set to true. So, when you tap on it, do you want callout or have it call didSelect? (Usually you'd do one or the other, but not both.) And are you seeing your callout?
I notice a curious behavior that if (a) the annotation doesn't have a title, and (b) the annotation view's canShowCallout is true, then not only can it not show the callout, but it also prevents the didSelect from being called.
You may either want to turn canShowCallout to false, or make sure your annotation has a title.