Skip to content

Instantly share code, notes, and snippets.

@rodydavis
Last active November 7, 2017 16:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rodydavis/c594c3cd899624751ae596e08d760127 to your computer and use it in GitHub Desktop.
Save rodydavis/c594c3cd899624751ae596e08d760127 to your computer and use it in GitHub Desktop.
View Controller for Map Kit (Get location from string)
//
// ContactMapView.swift
import UIKit
import MapKit
import Contacts
import CoreLocation
var addressString = "" //Pass Address String from other View Controllers
var fullnameString = "" //Pass a name you want to appear in the pop up on the map
class MapViewLocation: UIViewController {
var artworks: [Artwork] = []
let Contact = ContactDetails()
var lat = 37.783333
var lon = -122.416667
var myUserLat = 55.783333
var myUserLon = 85.783333
@IBOutlet weak var mapView: MKMapView!
// set initial location in Honolulu
var initialLocation = CLLocation(latitude: 21.282778, longitude: -157.829444)
let regionRadius: CLLocationDistance = 2000
func centerMapOnLocation(location: CLLocation) {
let coordinateRegion = MKCoordinateRegionMakeWithDistance(location.coordinate,
regionRadius, regionRadius)
mapView.setRegion(coordinateRegion, animated: true)
}
override func viewDidLoad() {
super.viewDidLoad()
title = "Address Lookup"
// Do any additional setup after loading the view.
// mapView.register(ArtworkView.self,
// forAnnotationViewWithReuseIdentifier: MKMapViewDefaultAnnotationViewReuseIdentifier)
//loadInitialData()
//mapView.addAnnotations(artworks)
mapView.delegate = self
//centerMapOnLocation(location: initialLocation)
// show artwork on map
// let artwork = Artwork(title: "King David Kalakaua",
// locationName: "Waikiki Gateway Park",
// discipline: "Sculpture",
// coordinate: CLLocationCoordinate2D(latitude: 21.283921, longitude: -157.831661))
// mapView.addAnnotation(artwork)
print("Address: " + addressString)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func map(address: String, title: String, name: String) {
let location = address
let geocoder = CLGeocoder()
geocoder.geocodeAddressString(location) { [weak self] placemarks, error in
if let placemark = placemarks?.first, let location = placemark.location {
//let mark = MKPlacemark(placemark: placemark)
let coordinates:CLLocationCoordinate2D = placemark.location!.coordinate
let artwork = Artwork(title: title,
locationName: name,
discipline: "Sculpture",
coordinate: CLLocationCoordinate2D(latitude: coordinates.latitude, longitude: coordinates.longitude))
if var region = self?.mapView.region {
region.center = location.coordinate
region.span.longitudeDelta /= 2500.0
region.span.latitudeDelta /= 2500.0
self?.mapView.setRegion(region, animated: true)
// self?.mapView.addAnnotation(mark)
self?.mapView.addAnnotation(artwork)
}
print("Lat: \(coordinates.latitude) -- Long: \(coordinates.longitude)")
self?.lat = coordinates.latitude
self?.lon = coordinates.longitude
}
}
}
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
let renderer = MKPolylineRenderer(polyline: overlay as! MKPolyline)
renderer.strokeColor = UIColor.blue
return renderer
}
func loadInitialData() {
// 1
guard let fileName = Bundle.main.path(forResource: "PublicArt", ofType: "json")
else { return }
let optionalData = try? Data(contentsOf: URL(fileURLWithPath: fileName))
guard
let data = optionalData,
// 2
let json = try? JSONSerialization.jsonObject(with: data),
// 3
let dictionary = json as? [String: Any],
// 4
let works = dictionary["data"] as? [[Any]]
else { return }
// 5
let validWorks = works.flatMap { Artwork(json: $0) }
artworks.append(contentsOf: validWorks)
}
let locationManager = CLLocationManager()
func checkLocationAuthorizationStatus() {
if CLLocationManager.authorizationStatus() == .authorizedWhenInUse {
mapView.showsUserLocation = true
} else {
locationManager.requestWhenInUseAuthorization()
}
}
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let locValue:CLLocationCoordinate2D = manager.location!.coordinate
print("locations = \(locValue.latitude) \(locValue.longitude)")
myUserLat = locValue.latitude
myUserLon = locValue.longitude
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
map(address: addressString, title: "Contact Location", name: fullnameString)
checkLocationAuthorizationStatus()
}
}
extension MapViewLocation: MKMapViewDelegate {
// 1
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
// 2
guard let annotation = annotation as? Artwork else { return nil }
// 3
let identifier = "marker"
var view: MKMarkerAnnotationView
// 4
if let dequeuedView = mapView.dequeueReusableAnnotationView(withIdentifier: identifier)
as? MKMarkerAnnotationView {
dequeuedView.annotation = annotation
view = dequeuedView
} else {
// 5
view = MKMarkerAnnotationView(annotation: annotation, reuseIdentifier: identifier)
view.canShowCallout = true
view.calloutOffset = CGPoint(x: -5, y: 5)
view.rightCalloutAccessoryView = UIButton(type: .detailDisclosure)
}
return view
}
func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView,
calloutAccessoryControlTapped control: UIControl) {
let location = view.annotation as! Artwork
let launchOptions = [MKLaunchOptionsDirectionsModeKey: MKLaunchOptionsDirectionsModeDriving]
location.mapItem().openInMaps(launchOptions: launchOptions)
}
}
class Artwork: NSObject, MKAnnotation {
let title: String?
let locationName: String
let discipline: String
let coordinate: CLLocationCoordinate2D
init(title: String, locationName: String, discipline: String, coordinate: CLLocationCoordinate2D) {
self.title = title
self.locationName = locationName
self.discipline = discipline
self.coordinate = coordinate
super.init()
}
init?(json: [Any]) {
// 1
self.title = json[16] as? String ?? "No Title"
// self.locationName = json[12] as! String
self.locationName = json[11] as! String
self.discipline = json[15] as! String
// 2
if let latitude = Double(json[18] as! String),
let longitude = Double(json[19] as! String) {
self.coordinate = CLLocationCoordinate2D(latitude: latitude, longitude: longitude)
} else {
self.coordinate = CLLocationCoordinate2D()
}
}
var subtitle: String? {
return locationName
}
var imageName: String? {
if discipline == "Sculpture" { return "Statue" }
return "Flag"
}
// markerTintColor for disciplines: Sculpture, Plaque, Mural, Monument, other
var markerTintColor: UIColor {
switch discipline {
case "Monument":
return .red
case "Mural":
return .cyan
case "Plaque":
return .blue
case "Sculpture":
return .purple
default:
return .green
}
}
// Annotation right callout accessory opens this mapItem in Maps app
func mapItem() -> MKMapItem {
let addressDict = [CNPostalAddressStreetKey: subtitle!]
let placemark = MKPlacemark(coordinate: coordinate, addressDictionary: addressDict)
let mapItem = MKMapItem(placemark: placemark)
mapItem.name = title
return mapItem
}
}
class ArtworkMarkerView: MKMarkerAnnotationView {
override var annotation: MKAnnotation? {
willSet {
// 1
guard let artwork = newValue as? Artwork else { return }
canShowCallout = true
calloutOffset = CGPoint(x: -5, y: 5)
rightCalloutAccessoryView = UIButton(type: .detailDisclosure)
// 2
markerTintColor = artwork.markerTintColor
// glyphText = String(artwork.discipline.first!)
if let imageName = artwork.imageName {
glyphImage = UIImage(named: imageName)
} else {
glyphImage = nil
}
}
}
}
class ArtworkView: MKAnnotationView {
override var annotation: MKAnnotation? {
willSet {
guard let artwork = newValue as? Artwork else {return}
canShowCallout = true
calloutOffset = CGPoint(x: -5, y: 5)
// rightCalloutAccessoryView = UIButton(type: .detailDisclosure)
let mapsButton = UIButton(frame: CGRect(origin: CGPoint.zero,
size: CGSize(width: 30, height: 30)))
mapsButton.setBackgroundImage(UIImage(named: "map-1"), for: UIControlState())
rightCalloutAccessoryView = mapsButton
if let imageName = artwork.imageName {
image = UIImage(named: imageName)
} else {
image = nil
}
let detailLabel = UILabel()
detailLabel.numberOfLines = 0
detailLabel.font = detailLabel.font.withSize(12)
detailLabel.text = artwork.subtitle
detailCalloutAccessoryView = detailLabel
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment