Calling mapView(_:viewFor:) when user location changes - swift

I want to have the user location being shown as a custom image (not the blue beacon). I also want that whenever the user location changes its coordinates, this custom image is rotated accordingly to represent the user course. In order to achieve that, I implemented the code below. It is being called with annotation type userLocation when the app is started, so that the user location custom image is being shown fine. The problem is that when I simulate a change in user location coordinates, the delegate mapView(_:viewFor:) method is never called again with an annotation type userLocation, so the image is never rotated. (Note: the UIImage rotateImage(by:) is a custom method).
Is there some means to call mapView(_:viewFor:) so that I can update the image annotation for user location when user location changes? Thanks for any help.
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
if annotation.isEqual(mapView.userLocation) {
// Annotation image for user location
let annotationView = MKAnnotationView(annotation: annotation, reuseIdentifier: nil)
annotationView.image = UIImage(named: "UserLocationImage.png")?.rotateImage(by: currentCourse)
return annotationView
}
}

Use CLLocationManagerDelegate
https://developer.apple.com/documentation/corelocation/cllocationmanagerdelegate
Implement this protocol in your code, and put your mapView function into its locationManager(_:didUpdateLocations:) method.

Related

SwiftUI MapKit - Multiple annotations in same map

I've had a look at similar questions but nothing seems to answer this question exactly.
I have a Map view and I want to add pin overlays, as well as a poly line route overlay on top of it. I am very very new at SwiftUI dev (this is my first app), so some help would be appreciated.
At the moment the map only renders the pins, and not the overlay. I'm assuming they need to be put into the same method but cannot figure out how you can return multiple overlays to the mapView.
Here is the Coordinator code:
class Coordinator: NSObject,MKMapViewDelegate{
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
//draw pins
if annotation.isKind(of: MKUserLocation.self){return nil}
else{
let pinAnnotation = MKPinAnnotationView(annotation: annotation, reuseIdentifier: "PIN_VIEW")
pinAnnotation.tintColor = .red
pinAnnotation.animatesDrop = true
pinAnnotation.canShowCallout = true
return pinAnnotation
}
}
private func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKPolylineRenderer? {
//draw route
let render = MKPolylineRenderer(overlay: overlay)
render.strokeColor = .orange
render.lineWidth = 2
return render;
}
}
Here is the output: (no route is drawn). I tried to put the annotations within the same method but couldn't figure out how to return both at the same time (pins are of type MKAnnotationView and the route is of type MKPolylineRenderer...
Help would be really appreciated. Thanks
It should be a separate method, but it shouldn’t be private. Also, the return type should be MKOverlayRenderer.

Adding MKAnnotation to MKMapView above location, not in center

I have this code in MapView Coordinator class for adding annotation to map:
func mapView(_ mapview: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
return mapview.dequeueReusableAnnotationView(withIdentifier: "myiconid")
}
Annotation added in center of my location :
How can I add annotation above my location?
The documentation says:
By default, the center point of an annotation view is placed at the coordinate point of the associated annotation. You can use this property to reposition the annotation view as needed. This x and y offset values are measured in points. Positive offset values move the annotation view down and to the right, while negative values move it up and to the left.
https://developer.apple.com/documentation/mapkit/mkannotationview/1452144-centeroffset
So you might want to change the centerOffset attribute for your annotations...
Annotation are set on the latitude and longitude that you provide while making it. I think there is no means we can place our annotation above our location unless we change our latitude and longitude.

MKAnnotationView tap on title

I want to customize my annotation view to show something like the image below. My questions are:
1) How can I customize the annotation view?
2) How can I make the app do something when user tap on the title? or tapped anywhere in the annotation view? if making it specific to the title is not possible!
I have added
func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl)
but it does not get called!

How in Swift to display details of multiple dropped pins

In Swift, I can add map annotation and display details using segue of a dropped pin when the user clicks the "i", but I am having trouble displaying details of multiple dropped pins using segue; unlike ViewTable no index is involved here. How do I do that?
Can this give you some hint?
func mapView(mapView: MKMapView!, annotationView view: MKAnnotationView!,
calloutAccessoryControlTapped control: UIControl!) {
//get the annotation ,maybe you need cast the type
// let anno = view.annotation
//performSegue here
}

Get Location From Center of Screen Swift MapKit

I'm new on Swift Programming, and I'm trying to build an app that I can get the coordinates of the center of the view with MapKit and Swift 2.
I already can get the current location, but I need if I move on the map, the location set to the new point which will be the center of the screen.
Can you help me with this please?.
Regards,
You can use the regionDidChangeAnimated delegate method and call mapView.centerCoordinate. It will look like the following:
func mapView(mapView: MKMapView, regionDidChangeAnimated animated: Bool) {
var center = mapView.centerCoordinate
}
Also make sure that your Class is extending MKMapViewDelegate and you are calling
self.mapView.delegate = self in your viewDidLoad() function.