How in Swift to display details of multiple dropped pins - swift

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
}

Related

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

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.

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!

Implementing gesture on a marker.iconView in swift 3 and google maps for ios

I've got a google map and i'm setting marker.iconView to a custom UIView.
marker.iconView = customUIView()
func customUIView()-> UIView
{
var theView:UIView
theView.isUserInteractionEnabled = true
let gesture = UITapGestureRecognizer(target: self, action:
#selector (self.popAction(sender:)))
theView.addGestureRecognizer(gesture)
}
The UIView is pretty much just a textbox and when the UIView is clicked I won't a popup happening from popAction.
But I can't get the gesture functionality to work and I wonder if it's because the gesture is being registered on the google map and not on the UIView.
**** Update *****
After reading the google docs i'm pretty sure i can't add a gesture to a marker.iconView because the UIView is just a "snapshot"
Instead i'm implementing GMSMapViewDelegate.
func mapView(_ mapView: GMSMapView, didTap marker: GMSMarker) -> Bool {
print("markerTapped")
return true
}
This function works but what i'd like to do is pass data from my UIView that is the marker.iconView into the above func mapView and not entirely sure how.
update
So marker.iconView = customUIView(sport: sportEvent) and each sportEvent object has title, date and description. The customUIView looks like a textbox with the info.
There is a loop through an array so that each marker on the map has specific sportEvent info.
Ideally, I'd like to add a gesture to the customUIView so that when the "marker" is clicked an alert pops up with the details of sportEvent title, date and description. But the way google renders marker.iconView means user input is lost from the customUIView so I can't set a gesture on it.
So i'm looking for a workaround where I can get a particular marker clicked and then an alert pops with that sportEvent info.
So I used GMSMapViewDelegate and then when the marker is clicked func mapView fires. That's cool but I can't get the sportEvent info associated with each particular marker.
So I tried to pass the sportEvent object into func mapView but then the function doesn't seem to execute and the marker is no longer clickable.
Thx.
The way I approached it was creating a custom GMSMarker. This will create the points on your mapView.
You want to pass in your sportEvent object when initializing the custom marker (i.e. something like CustomMarker(with: sportEvent))
The GMSMarker object has some properties you can set which you can find here but, some of the notable ones include:
title, snippet (text beneath title) which is what you want to set from your sportEvent object.
So, in your custom marker you can do:
Class CustomMarker: GMSMarker {
var title: String
var desc: String
...
init(with sportEvent: SportEvent) {
// do some validation before setting this assumes all values are set correctly
self.title = sportEvent.title //(assuming `.title` is a string)
self.desc = sportEvent.description
...
super.init()
title = self.title
snippet = self.desc
}
}
Note that the custom GMSMarker may need a position property set which is just a CLLocationCoordinate2D i.e. (position = CLLocationCoordinate2D(latitude: sportEvent.latitude, longitude: sportEvent.longitude)
This will by default show you a mini marker info window with your sportEvent object.
If you want to further customize the marker info window you can take a look at markerInfoWindow
It returns a view if it exists. What I did was create my view programatically and I passed in my custom marker into the view and set everything accordingly there.
Like so:
func mapView(_ mapView: GMSMapView, markerInfoWindow marker: GMSMarker) -> UIView? {
let customMarker = marker as! CustomMarker
return myCustomView(with: customMarker)
}
Where myCustomView is a method that returns a UIView`
func myCustomView(with customMarker: CustomMarker) -> UIView {
// Set view programatically here with your customMarker
}
Hope it helps!

Check which annotation is tapped, and use this information into a button code implementation

I have some annotations in my map. I need to slide them with a button that focus on them, one by one. I use this function to see if an annotation is tapped:
func mapView(mapView: MKMapView!, didSelectAnnotationView view: MKAnnotationView!)
{
println("Annotation tapped \(view.annotation.title)")
}
How can i use it, in the implementation of my button function? This is my button code:
#IBAction func nextAnnotation(sender: UIButton)
{
// here i want to know which annotation is pressed, so i can move to the next.
}
I have all the annotations stored into an array. How can i check what annotation is tapped, and use this information into the button code implementation?
Thanks

Can we get all the annotation views from MKMapView

Is there any direct method or any suggestion on how to get all the annotations from the MKMapView?
You can access map's annotations using its annotations property. Getting views for all annotations may not be always possible as annotations that are not currently visible on the map may have no views associated with them, but for arbitrary annotation you can try to get a view using -viewForAnnotation: method.
So here how you can iterate through all map's annotations and try to access their views:
for (id<MKAnnotation> annotation in mapView.annotations){
MKAnnotationView* anView = [mapView viewForAnnotation: annotation];
if (anView){
// Process annotation view
...
}
}
In swift 3.
func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) {
let selectedAnnotation = view.annotation
for annotation in mapView.annotations {
let viewI = mapView.view(for: annotation)
if !(viewI?.annotation is MKUserLocation){
if annotation.isEqual(selectedAnnotation) {
viewI?.image = UIImage(named: "focus.png")
showLifeEventView(anotation: view) //did select a point on Map.
}else{
viewI?.image = UIImage(named: "point.png")
}
}
}
}