Last active
November 7, 2017 16:11
-
-
Save rodydavis/c594c3cd899624751ae596e08d760127 to your computer and use it in GitHub Desktop.
View Controller for Map Kit (Get location from string)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// 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