I was wondering if anyone could help me with my Xcode iOS Swift App. I'm very new to coding, and I'm trying to drop a custom pin/annotation with a title/subtitle/image when a user clicks a certain button from a menu but I can't get the pin to show up when its within the button's IBAction function. However, when I remove the func mapView from the IBAction and just place it within the UIViewController class, the pin drop does work (when I test it at another coordinate) but the problem is that it appears automatically upon the home screen loading. When I include the mapView function within the IBAction button, nothing happens and the custom annotation doesn't appear.
It also makes the current location blue user dot disappear for some reason. I was wondering if someone can help either just remove the initial automatic loading of the custom pin and only execute the relevant function when the correct button is clicked. Right now I'm just focusing on UI so the coordinate points to Alcatraz in SF. Thanks so much!!
I've attached the relevant code below.
View controller code:
var locationManager = CLLocationManager()
var tulipPin:customPin!
@IBOutlet weak var mapView: MKMapView!
@IBAction func tulipButton(_ sender: Any) {
tulipPin = customPin(Title: "username", Subtitle: "caption", coordinate:CLLocationCoordinate2D(latitude: 37.8270, longitude: -122.4230))
tulipPin.image = UIImage(named: "tulip")
self.mapView.addAnnotation(tulipPin)
}
func mapView(_ mapview: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
let annotationView = MKAnnotationView(annotation: tulipPin, reuseIdentifier: "tulip")
annotationView.image = UIImage(named: "tulip")
annotationView.canShowCallout = true
annotationView.calloutOffset = CGPoint(x: -5, y: 5)
let transform = CGAffineTransform(scaleX: 0.07, y: 0.07)
annotationView.transform = transform
return annotationView
}
Plus other relevant location code that may be useful to decipher:
func determineCurrentLocation()
{
mapView.delegate = self
locationManager = CLLocationManager()
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestAlwaysAuthorization()
if CLLocationManager.locationServicesEnabled() {
locationManager.startUpdatingLocation()
}
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
mapView.delegate = self
let center = CLLocationCoordinate2D(latitude: 37.8270, longitude: -122.4230)
let region = MKCoordinateRegion(center: center, span: MKCoordinateSpan(latitudeDelta: 0.01, longitudeDelta: 0.01))
mapView.setRegion(region, animated: true)
Here is the viewDidLoad function on the home viewcontroller:
override func viewDidLoad() {
super.viewDidLoad()
regionSet()
determineCurrentLocation()
}
And my customPin class:
import Foundation
import MapKit
class customPin: NSObject, MKAnnotation {
@IBOutlet weak var mapView: MKMapView!
var coordinate: CLLocationCoordinate2D
var title: String?
var subtitle: String?
var image: UIImage? = nil
init(Title: String, Subtitle: String, coordinate:CLLocationCoordinate2D) {
self.title = Title
self.subtitle = Subtitle
self.coordinate = coordinate
//self.image
super.init()
}
}
Interesting, I tested your code, altering the coordinates to be in New York (simulator location) and the button works fine for me. Are you sure your custom coordinates are where you want them? And why not use the user's location?
Try this:
func determineCurrentLocation() {
mapView.delegate = self
locationManager = CLLocationManager()
locationManager.delegate = self
mapView.showsUserLocation = true
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestAlwaysAuthorization()
if CLLocationManager.locationServicesEnabled() {
locationManager.startUpdatingLocation()
}
}
@IBAction func tulipButton(_ sender: Any) {
dropPin()
}
func dropPin() { // Using the user's location
guard let location = locationManager.location else { return }
let center = CLLocationCoordinate2D(latitude: location.coordinate.latitude, longitude: location.coordinate.longitude)
tulipPin = customPin(Title: "username", Subtitle: "caption", coordinate: center)
self.mapView.addAnnotation(tulipPin)
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
guard let location = locationManager.location else { return }
let center = CLLocationCoordinate2D(latitude: location.coordinate.latitude, longitude: location.coordinate.longitude)
let region = MKCoordinateRegion(center: center, span: MKCoordinateSpan(latitudeDelta: 0.05, longitudeDelta: 0.05))
mapView.setRegion(region, animated: true)
}
func mapView(_ mapview: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
guard !(annotation is MKUserLocation) else { return nil }
let annotationView = MKAnnotationView(annotation: tulipPin, reuseIdentifier: "tulip")
annotationView.image = UIImage(named: "tulip")
annotationView.canShowCallout = true
annotationView.calloutOffset = CGPoint(x: -5, y: 5)
// let transform = CGAffineTransform(scaleX: 0.07, y: 0.07)
// annotationView.transform = transform
return annotationView
}