MKAnnotationView Swift Adding "Info" button - ios

I am very new to swift (coming from python) I am struggling with creating a MKAnnotationView. I followed a tutorial by ray wenderlich but the code appears to be outdated. The function call does not seem to work or produce the "i" intended to be in the annotation of the pin. Here is the code I am currently using:
import MapKit
extension ViewController: MKMapViewDelegate {
// 1
func mapView(mapView: MKMapView!, viewForAnnotation annotation: MKAnnotation!) -> MKAnnotationView! {
if let annotation = annotation as? Artwork {
let identifier = "pin"
var view: MKPinAnnotationView
if let dequeuedView = MapView.dequeueReusableAnnotationView(withIdentifier: identifier)
as? MKPinAnnotationView { // 2
dequeuedView.annotation = annotation
view = dequeuedView
} else {
// 3
view = MKPinAnnotationView(annotation: annotation, reuseIdentifier: identifier)
view.canShowCallout = true
view.calloutOffset = CGPoint(x: -5, y: 5)
let button = UIButton(type:.detailDisclosure)
view.rightCalloutAccessoryView = button as UIView
}
return view
}
return nil
}
}
I am running Xcode 8.1, any help will be greatly appreciated.

Am using Xcode 8.1 and Swift 3.0 . For Some reason Delegate methods are not firing until you set delegate in storyboard:
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView?
{
if annotation is MKUserLocation {return nil}
let reuseId = "pin"
var pinView = mapView.dequeueReusableAnnotationView(withIdentifier: reuseId) as? MKPinAnnotationView
if pinView == nil {
pinView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: reuseId)
pinView!.canShowCallout = true
pinView!.animatesDrop = true
let calloutButton = UIButton(type: .DetailDisclosure)
pinView!.rightCalloutAccessoryView = calloutButton
pinView!.sizeToFit()
}
else {
pinView!.annotation = annotation
}
return pinView
}
for button Action
func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) {
if control == view.rightCalloutAccessoryView {
print("button tapped")
}
}
I am attaching sample project for your issue
Map Sample Project Swift 3. 0 Xcode 8.1

Related

MKMarkerAnnotationView not showing callout

I am currently working on creating callouts for annotations I have added to my mapview via MapKit. The annotations work out well but currently callouts aren't being displayed even though I am using the right code to enable them (I believe).
HERE is my viewFor annotation code block.
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
if annotation is MKUserLocation {
return nil
}
if let annotation = annotation as? ClusterAnnotation {
let identifier = "cluster"
return mapView.annotationView(annotation: annotation, reuseIdentifier: identifier)
} else {
let identifier = "pin"
let annotationView = mapView.annotationView(of: MKMarkerAnnotationView.self, annotation: annotation, reuseIdentifier: identifier)
annotationView.isEnabled = true
annotationView.canShowCallout = true
annotationView.accessibilityLabel = "hi"
annotationView.isHidden = false
annotationView.rightCalloutAccessoryView = UIButton(type: .detailDisclosure)
annotationView.markerTintColor = UIColor.customBlue()
annotationView.glyphImage = UIImage(named: "person")
return annotationView
}
}
Extension code block for annotationView function.
extension MKMapView {
func annotationView<T: MKAnnotationView>(of type: T.Type, annotation: MKAnnotation?, reuseIdentifier: String) -> T {
guard let annotationView = dequeueReusableAnnotationView(withIdentifier: reuseIdentifier) as? T else {
return type.init(annotation: annotation, reuseIdentifier: reuseIdentifier)
}
annotationView.annotation = annotation
return annotationView
}
}
The annotation enlarges as I select it, and in the didSelect code block it runs the print statement I run through it. Not exactly sure what is going on that's not allowing the callout to show even though I've literally enabled just about everything.
Please Used This Code.
This code working fine for me.
This Code support Swift4 and Swift5.
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
// Don't want to show a custom image if the annotation is the user's location.
if (annotation is MKUserLocation) {
return nil
} else {
let annotationIdentifier = "AnnotationIdentifier"
let nibName = "MyAnnotationView" //My XIB Name
let viewFromNib = Bundle.main.loadNibNamed(nibName, owner: self, options: nil)?.first as! MyAnnotationView // get My XIB
var annotationView: MyAnnotationView?
// if there is a view to be dequeued, use it for the annotation
if let dequeuedAnnotationView = mapView.dequeueReusableAnnotationView(withIdentifier: annotationIdentifier) as? MyAnnotationView {
if dequeuedAnnotationView.subviews.isEmpty {
dequeuedAnnotationView.addSubview(viewFromNib)
}
annotationView = dequeuedAnnotationView
annotationView?.annotation = annotation
} else {
// if no views to dequeue, create an Annotation View
let av = MyAnnotationView(annotation: annotation, reuseIdentifier: annotationIdentifier)
av.addSubview(viewFromNib)
annotationView = av // extend scope to be able to return at the end of the func
}
// after we manage to create or dequeue the av, configure it
if let annotationView = annotationView {
annotationView.canShowCallout = true // callout bubble
annotationView.rightCalloutAccessoryView = UIButton(type: .detailDisclosure)
annotationView.frame = CGRect(x: 0, y: 0, width: 75, height: 80)
let customView = annotationView.subviews.first as! MyAnnotationView
customView.frame = annotationView.frame
}
return annotationView
}
}
This Code OutPut :
Happy To Help You.
From the source code documentation:
// If YES, a standard callout bubble will be shown when the annotation is selected.
// The annotation must have a title for the callout to be shown.
#property (nonatomic) BOOL canShowCallout;
Without the Title value being set the other items will not show up.

How to edit glyph image icons Swift 4?

I am new to swift 4.2, and I was wondering can I edit the glyph-image pin icon in swift 4. For example, instead of the red marker with the pin could it be an as red marker with fast food icon? Thanks for the help.
Here is my code:
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
let identifier = "marker"
var view: MKMarkerAnnotationView
if let dequeuedView = mapView.dequeueReusableAnnotationView(withIdentifier: identifier)
as? MKMarkerAnnotationView {
dequeuedView.annotation = annotation
view = dequeuedView
} else {
view = MKMarkerAnnotationView(annotation: annotation, reuseIdentifier: identifier)
view.canShowCallout = true
view.calloutOffset = CGPoint(x: -5, y: 5)
view.rightCalloutAccessoryView = UIButton(type: .detailDisclosure)
}
return view
}
You can't edit it, but you can certainly replace it. Just set the MKMarkerAnnotationView's glyphImage.

Change Pin's color in MapKit - Swift 4 - Xcode 10 - iOS 12

I am trying to change the color of the pin used in my map in MapKit in Xcode. I found this in the Apple Developer Documentation:
Declaration (iOS, tvOS):
var pinTintColor: UIColor! { get set }
I am new to code and I can't figure out what I should put in get and set, could you please help me?
Thank you!
Try the following code:
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
if annotation is MKUserLocation {
return nil
}
let reuseId = "pin"
var pinView = mapView.dequeueReusableAnnotationView(withIdentifier: reuseId) as? MKPinAnnotationView
if pinView == nil {
pinView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: reuseId)
pinView?.pinTintColor = .purple
}
else {
pinView?.annotation = annotation
}
return pinView
}

Swift map annotations

I am trying to get an annotation on the user location but I can't get a (sort of) speech bubble for my annotation's details. Is there any option to create something like this?
//AnnotationSettings
let newPin = MKPointAnnotation()
//set region on the map
maphome.setRegion(region, animated: true)
newPin.coordinate = location.coordinate
newPin.title = "aksldfjaskldfjaklsdfa"
newPin.subtitle = "sounds awesome!"
maphome.addAnnotation(newPin)
This is my code for the annotation.
You should set canShowCallout = true.
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
if annotation is MKUserLocation {
return nil
}
let reuseId = "pin"
var pinView = mapView.dequeueReusableAnnotationView(withIdentifier: reuseId) as? MKMarkerAnnotationView
if pinView == nil {
pinView = MKMarkerAnnotationView(annotation: annotation, reuseIdentifier: reuseId)
pinView?.canShowCallout = true
let rightButton: AnyObject! = UIButton(type: UIButtonType.detailDisclosure)
pinView?.rightCalloutAccessoryView = rightButton as? UIView
}
else {
pinView?.annotation = annotation
}
return pinView
}
yes, you can try this
func mapView(_ mapView: MGLMapView, annotationCanShowCallout annotation: MGLAnnotation) -> Bool {
// Always allow callouts to popup when annotations are tapped.
return true
}

Show Annotation Title and SubTitle in Custom MKPinAnnotationView

I am using MKPinAnnotationView inside my App.
I am setting MapView object as delegate, and using this code for customising my AnnotationView
func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? {
if annotation is MKUserLocation {
//return nil so map view draws "blue dot" for standard user location
return nil
}
let reuseId = "pin"
var pinView = mapView.dequeueReusableAnnotationViewWithIdentifier(reuseId) as? MKPinAnnotationView
if pinView == nil {
pinView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: reuseId)
// pinView!.canShowCallout = true
pinView!.image = UIImage(named:"store.jpg")
pinView!.animatesDrop = true
pinView!.pinTintColor = UIColor.darkGrayColor()
}
else {
pinView!.annotation = annotation
}
return pinView
}
I am getting custom AnnotationView as I required.However, I am missing the features of title and subtitle of MKPointAnnotation.
I wish to see title and subtitle for the grey dots.
I was overriding one func
func mapView(mapView: MKMapView, didSelectAnnotationView view: MKAnnotationView) {
mapView.deselectAnnotation(view.annotation, animated: true)
}
I commented this function out and got the titles and subtitles.
Updated Code
/*
func mapView(mapView: MKMapView, didSelectAnnotationView view: MKAnnotationView) {
mapView.deselectAnnotation(view.annotation, animated: true)
}
*/
func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? {
if annotation is MKUserLocation {
//return nil so map view draws "blue dot" for standard user location
return nil
}
let reuseId = "pin"
let pinView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: reuseId)
pinView.canShowCallout = true
pinView.animatesDrop = true
pinView.pinTintColor = UIColor.darkGrayColor()
pinView.draggable = true
pinView.accessibilityLabel = "hello"
let btn = UIButton(type: .DetailDisclosure)
pinView.rightCalloutAccessoryView = btn
return pinView
}

Resources