I have a label named "direction". I have a map with a lot of pins. When i click on one pin and tap the label "direction" it give me two options and works fine. But when i do not click on a Pin and tap de label "direction" the app crash.
i want to setup an statement when the a pin is not selected an alert show that the user first select a pin to get directions.
Hope someone can look at code to make this possible:
import UIKit
import MapKit
class ViewController: UIViewController, CLLocationManagerDelegate, MKMapViewDelegate, GMSMapViewDelegate {
#IBOutlet weak var mapView: GMSMapView!
#IBAction func MapType(sender: AnyObject) {
let segmentedControl = sender as! UISegmentedControl
switch segmentedControl.selectedSegmentIndex {
case 0:
mapView.mapType = kGMSTypeNormal
case 1:
mapView.mapType = kGMSTypeSatellite
case 2:
mapView.mapType = kGMSTypeHybrid
default:
mapView.mapType = mapView.mapType
}
}
let locationManager = CLLocationManager()
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
//3
mapView.delegate = self
locationManager.delegate = self
locationManager.requestWhenInUseAuthorization()
var Marker= GMSMarker()
Marker.position = CLLocationCoordinate2DMake(5.2317, 4.5708 )
Marker.title = "1"
Marker.snippet = "1"
Marker.appearAnimation = kGMSMarkerAnimationPop
Marker.map = mapView
var Marker1= GMSMarker()
Marker1.position = CLLocationCoordinate2DMake(5.2317, 8.5708 )
Marker1.title = "2"
Marker1.snippet = "2"
Marker1.map = mapView
let label = UILabel(frame: CGRectMake(view.frame.size.width - 100, view.frame.size.height - 40, 80, 30))
label.backgroundColor = UIColor.whiteColor()
label.text = "direction"
label.textAlignment = .Center
label.layer.cornerRadius = 10
label.clipsToBounds = true
label.userInteractionEnabled = true
let tap = UITapGestureRecognizer(target: self, action: "directionTapped")
label.addGestureRecognizer(tap)
mapView!.settings.consumesGesturesInView = false
mapView!.addSubview(label)
mapView!.bringSubviewToFront(label)
self.view.addSubview(label)
}
func directionTapped() {
let openMapsActionSheet = UIAlertController(title: "Open in Maps", message: "Choose a maps application", preferredStyle: .ActionSheet)
openMapsActionSheet.addAction(UIAlertAction(title: "Apple Maps", style: .Default, handler: { (action: UIAlertAction!) -> Void in
let placemark = MKPlacemark(coordinate: CLLocationCoordinate2DMake(self.mapView!.selectedMarker.position.latitude, self.mapView!.selectedMarker.position.longitude), addressDictionary: nil)
let item = MKMapItem(placemark: placemark)
let options = [MKLaunchOptionsDirectionsModeKey:
MKLaunchOptionsDirectionsModeDriving,
MKLaunchOptionsShowsTrafficKey: true]
item.openInMapsWithLaunchOptions(options as [NSObject : AnyObject])
}))
openMapsActionSheet.addAction(UIAlertAction(title: "Google Maps", style: .Default, handler: { (action: UIAlertAction!) -> Void in
if (UIApplication.sharedApplication().canOpenURL(NSURL(string:"comgooglemaps://")!)) {
UIApplication.sharedApplication().openURL(NSURL(string:
"comgooglemaps://?daddr=\(self.mapView!.selectedMarker.position.latitude),\(self.mapView!.selectedMarker.position.longitude)")!)
} else {
UIApplication.sharedApplication().openURL(NSURL(string:
"http://maps.google.com/maps?daddr=\(self.mapView!.selectedMarker.position.latitude),\(self.mapView!.selectedMarker.position.longitude)")!)
}
}))
openMapsActionSheet.addAction(UIAlertAction(title: "Cancel", style: .Cancel, handler: nil))
presentViewController(openMapsActionSheet, animated: true, completion: nil)
}
// 1
func locationManager(manager: CLLocationManager!, didChangeAuthorizationStatus status: CLAuthorizationStatus) {
// 2
if status == .AuthorizedWhenInUse {
// 3
locationManager.startUpdatingLocation()
//4
mapView.myLocationEnabled = true
mapView.settings.myLocationButton = true
}
}
// 5
func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!) {
if let location = locations.first as? CLLocation {
// 6
mapView.camera = GMSCameraPosition(target: location.coordinate, zoom: 6, bearing: 1, viewingAngle: 1)
// 7
locationManager.stopUpdatingLocation()
}
}
}
In absence of the complete code, here is what i can extrapolate:
I am assuming you have a mapView that is already set.
I am assuming mapView!.selectedMarker gets populated only when the user selects the pin, else it is nil (or some other value u choose) then,
Now, directionTapped should be:
if self.mapView!.selectedMarker != nil {
<Your current Code>
} else {
<Code to Show the new alert about pin not selected>
}
with this code it worked from me:
func directionTapped(){
//code input from Apple-and-Oranges
if self.mapView!.selectedMarker != nil {
//current code
let openMapsActionSheet = UIAlertController(title: "Open in Maps", message: "Choose a maps application", preferredStyle: .ActionSheet)
openMapsActionSheet.addAction(UIAlertAction(title: "Apple Maps", style: .Default, handler: { (action: UIAlertAction!) -> Void in
let placemark = MKPlacemark(coordinate: CLLocationCoordinate2DMake(self.mapView!.selectedMarker.position.latitude, self.mapView!.selectedMarker.position.longitude), addressDictionary: nil)
let item = MKMapItem(placemark: placemark)
let options = [MKLaunchOptionsDirectionsModeKey:
MKLaunchOptionsDirectionsModeDriving,
MKLaunchOptionsShowsTrafficKey: true]
item.openInMapsWithLaunchOptions(options as [NSObject : AnyObject])
}))
openMapsActionSheet.addAction(UIAlertAction(title: "Google Maps", style: .Default, handler: { (action: UIAlertAction!) -> Void in
if (UIApplication.sharedApplication().canOpenURL(NSURL(string:"comgooglemaps://")!)) {
UIApplication.sharedApplication().openURL(NSURL(string:
"comgooglemaps://?daddr=\(self.mapView!.selectedMarker.position.latitude),\(self.mapView!.selectedMarker.position.longitude)")!)
} else {
UIApplication.sharedApplication().openURL(NSURL(string:
"http://maps.google.com/maps?daddr=\(self.mapView!.selectedMarker.position.latitude),\(self.mapView!.selectedMarker.position.longitude)")!)
}
}))
openMapsActionSheet.addAction(UIAlertAction(title: "Cancel", style: .Cancel, handler: nil))
presentViewController(openMapsActionSheet, animated: true, completion: nil)
}
//Added a alert message
else {
let alertController = UIAlertController(title: "Choose Pin!", message: "\nChoose Pin to get navigation from current location", preferredStyle: .Alert)
alertController.addAction(UIAlertAction(title: "Cancel", style: .Default, handler: { (action: UIAlertAction!) in
}))
presentViewController(alertController, animated: true, completion: nil)
}
}
Related
I want to send the location messages using firebase. like when user click on button it shows alert which message you want to send like audio,video,location.When user select the location from the given option it will call locationViewController and store the location in firebase.I've simple loaded the google map with marker pin point and defined the coordinates it's self not dynamically. InputActionSheet func that defined in chatViewController when user tap on choose button this function call and inside another function call that will call the functionality of location messages.But I'm confused how we get get coordinates dynamically when user taped on any location on google map and also it will show the marker when user tap.
SimpleViewController class for checking the functionality of google map it's working fine:
class ViewController: UIViewController {
#IBOutlet weak var mapView: GMSMapView!
let manager = CLLocationManager()
let karachi = CLLocationCoordinate2D(latitude: 24.882752, longitude: 67.149848)
let tandoAdam = CLLocationCoordinate2D(latitude: 25.76284, longitude: 68.66087)
override func viewDidLoad() {
super.viewDidLoad()
self.setupMap(title: "Karachi", subtitle: "Shah Faisal", karachi)
self.setupMap(title: "TDM", subtitle: "AK H", tandoAdam)
self.mapView.mapStyle(name:"darkTheme", type:"json")
}
func setupMap(title:String,subtitle:String,_ coordinate:CLLocationCoordinate2D){
manager.delegate = self
manager.requestWhenInUseAuthorization()
manager.startUpdatingLocation()
let camera = GMSCameraPosition.camera(withLatitude: coordinate.latitude, longitude: coordinate.longitude, zoom: 6.0)
mapView.camera = camera
mapView.camera = camera
self.addMarker(title: title, subtitle: subtitle, coordinate:coordinate)
}
func addMarker(title:String,subtitle:String,coordinate:CLLocationCoordinate2D){
let marker = GMSMarker()
marker.icon = #imageLiteral(resourceName: "DiceFive")
marker.position = coordinate
marker.title = title
marker.snippet = subtitle
marker.map = mapView
}
}
extension UIViewController : CLLocationManagerDelegate {
public func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
guard locations.first != nil else{
return
}
}
}
presentInputActionSheet func in Chat class:
private func presentInputActionSheet() {
let actionSheet = UIAlertController(title: "Attach Media",
message: "What would you like to attach?",
preferredStyle: .actionSheet)
actionSheet.addAction(UIAlertAction(title: "Photo", style: .default, handler: { [weak self] _ in
self?.presentPhotoInputActionsheet()
}))
actionSheet.addAction(UIAlertAction(title: "Video", style: .default, handler: { [weak self] _ in
self?.presentVideoInputActionsheet()
}))
actionSheet.addAction(UIAlertAction(title: "Audio", style: .default, handler: { _ in
}))
actionSheet.addAction(UIAlertAction(title: "Location", style: .default, handler: { [weak self] _ in
self?.presentLocationPicker()
}))
actionSheet.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
present(actionSheet, animated: true)
}
presentLocationPicker func in Chat class:
private func presentLocationPicker() {
let vc = ViewController(coordinates: nil)
vc.title = "Pick Location"
vc.navigationItem.largeTitleDisplayMode = .never
let location = Location(location: CLLocation(latitude: latitude, longitude: longitude),
size: .zero)
let message = Message(sender: selfSender,messageId: messageId,sentDate: Date(),kind: .location(location))
DatabaseManager.shared.sendMessage(to: conversationId, otherUserEmail: strongSelf.otherUserEmail, name: name, newMessage: message, completion: { success in
if success {
print("sent location message")
}
else {
print("failed to send location message")
}
})
}
navigationController?.pushViewController(vc, animated: true)
}
try this
let message = Message(sender: selfSender,messageId: messageId,sentDate: Date(),kind: .location(location))
DatabaseManager.shared.sendMessage(to: conversationId, otherUserEmail: strongSelf.otherUserEmail, name: name, newMessage: message, completion: { success in
if success {
print("sent location message")
}
else {
print("failed to send location message")
}
navigationController?.pushViewController(vc, animated: true)
})
}
So, at the moment I can't seem to figure out how the user can enter a title on the Annotation pins. In my code a pin will appear after a long press on the map, but the title shown of the pin is "Pin".
The only thing I would like to be able to do is for the user of the app to be able to create unique titles of the pins on creation.
import Foundation
import UIKit
import MapKit
class MapsViewController: UIViewController, CLLocationManagerDelegate {
let locationManager:CLLocationManager = CLLocationManager()
#IBOutlet weak var mapView: MKMapView!
override func viewDidLoad() {
super.viewDidLoad()
locationManager.delegate = self
locationManager.requestWhenInUseAuthorization()
locationManager.startUpdatingLocation()
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
for currentLocation in locations{
print("\(index) : \(currentLocation)")
}
}
#IBAction func addPin(_ sender: UILongPressGestureRecognizer) {
let alert = UIAlertController(title: "Title", message: "Please enter location name", preferredStyle: .alert)
//2. Add the text field. You can configure it however you need.
alert.addTextField { (textField) in
textField.text = "Location name"
}
// 3. Grab the value from the text field, and print it when the user clicks OK.
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: { [weak alert] (_) in
let textField = alert?.textFields![0] // Force unwrapping because we know it exists.
print("Text field: \(String(describing: textField?.text))")
DispatchQueue.main.async { self.addPinWithTitle (sender , title : textField?.text ?? "") }
}))
self.present(alert, animated: true, completion: nil)}
func addPinWithTitle(_ sender: UILongPressGestureRecognizer , title : String) {
let location = sender.location(in: self.mapView)
let locCoordinates = self.mapView.convert(location, toCoordinateFrom: self.mapView)
let annotation = MKPointAnnotation()
annotation.coordinate = locCoordinates
annotation.title = title
self.mapView.addAnnotation(annotation)}
}
Please follow the final code
#IBAction func addPin(_ sender: UILongPressGestureRecognizer) {
let alert = UIAlertController(title: "Title", message: "Please enter location name", preferredStyle: .alert)
//2. Add the text field. You can configure it however you need.
alert.addTextField { (textField) in
textField.placeholder = "Location name"
}
// 3. Grab the value from the text field, and print it when the user clicks OK.
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: { [weak alert] (_) in
let textField = alert?.textFields![0] // Force unwrapping because we know it exists.
print("Text field: \(textField?.text)")
DispatchQueue.main.async {
self.addPinWithTitle (sender , title : textField?.text ?? "")
}
}))
self.present(alert, animated: true, completion: nil)}
func addPinWithTitle(_ sender: UILongPressGestureRecognizer , title : String) {
let location = sender.location(in: self.mapView)
let locCoordinates = self.mapView.convert(location, toCoordinateFrom: self.mapView)
let annotation = MKPointAnnotation()
annotation.coordinate = locCoordinates
annotation.title = title
self.mapView.addAnnotation(annotation)}
in my app i want to use alert controller so am using the following code:
import UIKit
import CoreLocation
class GPSTrackingManager: NSObject,CLLocationManagerDelegate {
var locationManager: CLLocationManager!
var seenError : Bool = false
func startTracking() {
locationManager = CLLocationManager()
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestAlwaysAuthorization()
locationManager.startUpdatingLocation()
}
func locationManager(manager: CLLocationManager, didFailWithError error: NSError) {
locationManager.stopUpdatingLocation()
print("error occured:\(error)")
}
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
//println("locations = \(locationManager)")
let latValue = locationManager.location!.coordinate.latitude
let lonValue = locationManager.location!.coordinate.longitude
print(latValue)
print(lonValue)
GoogleLat = latValue
GoogleLong = lonValue
CLGeocoder().reverseGeocodeLocation(manager.location!, completionHandler: {(placemarks, error)->Void in
if (error != nil)
{
print("Reverse geocoder failed with error" + error!.localizedDescription)
return
}
if placemarks!.count > 0
{
let pm = placemarks![0] as CLPlacemark
self.displayLocationInfo(pm)
}
else
{
print("Problem with the data received from geocoder")
}
})
}
func displayLocationInfo(placemark: CLPlacemark?)
{
if let containsPlacemark = placemark
{
locationManager.stopUpdatingLocation()
let fourthcity = (containsPlacemark.subAdministrativeArea != nil) ? containsPlacemark.subAdministrativeArea : ""
let fourthState = (containsPlacemark.administrativeArea != nil) ? containsPlacemark.administrativeArea : ""
let fourthCountry = (containsPlacemark.country != nil) ? containsPlacemark.country : ""
print("my Real City = \(fourthcity)")
let fullName = fourthcity
let fullNameArr = fullName!.characters.split{$0 == " "}.map(String.init)
fullNameArr[0]
print(fullNameArr[0])
print("myState = \(fourthState)")
print("myCountry = \(fourthCountry)")
appDelCityname = fullNameArr[0]
appDelStateName = fourthState
appDelCountryName = fourthCountry
print("AppDelegate City Name = \(appDelCityname)")
}
}
func locationManager(manager: CLLocationManager, didChangeAuthorizationStatus status: CLAuthorizationStatus) {
switch status {
case .NotDetermined:
// If status has not yet been determied, ask for authorization
manager.requestWhenInUseAuthorization()
break
case .AuthorizedWhenInUse:
// If authorized when in use
print("AuthorizedWhenInUse")
manager.startUpdatingLocation()
break
case .AuthorizedAlways:
// If always authorized
print("AuthorizedAlways")
manager.startUpdatingLocation()
break
case .Denied:
// If user denied your app access to Location Services, but can grant access from Settings.app
print("user denied to allow")
dispatch_async(dispatch_get_main_queue(), {
NSTimer.scheduledTimerWithTimeInterval(3.0,target: self, selector: #selector(self.DisplayalertToturnonLocation), userInfo: nil, repeats: false)
})
break
default:
print("user cant allow location service")
break
}
}
func DisplayalertToturnonLocation(){
let alertController = UIAlertController(title: "GPRS is Required", message: "This app requires your location,please turn on your location service or set your address", preferredStyle: .Alert)
let saveAction = UIAlertAction(title: "Set Address", style: UIAlertActionStyle.Default, handler: {
alert -> Void in
self.alertTogetAdrressFromUser()
})
alertController.addAction(saveAction)
let cancelAction = UIAlertAction(title: "Settings", style: UIAlertActionStyle.Default, handler: {
(action : UIAlertAction!) -> Void in
UIApplication.sharedApplication().openURL(NSURL(string: UIApplicationOpenSettingsURLString)!)
})
alertController.addAction(cancelAction)
let keyWindow = UIApplication.sharedApplication().keyWindow
let mainController = keyWindow!.rootViewController!
mainController.presentViewController(alertController, animated: true, completion: nil)
}
}
I am calling this function in AppDelegate which executes well in iPad but not in iPhone also it not shows any error or warning and am feeling too difficult to find what am doing wrong here so any one help me to display alert controller in iPhone.
in AppDelegate:
var tracking = GPSTrackingManager()
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
tracking.startTracking()
}
in here you need to follow two things . 1. your code is fine you need to show ur alertcontroller using main thread, else find the root wihch one is most top presnt your alert, else check once your current window is visible or not
present your UIAlertcontroller in Main thread, for e.g
Swift3
DispatchQueue.main.async {
self.tracking.DisplayalertToturnonLocation()
}
swift2
dispatch_async(dispatch_get_main_queue()) {
self.tracking.DisplayalertToturnonLocation()
}
you get the output as
full code
class GPSTrackingManager: NSObject {
func DisplayalertToturnonLocation(){
let alertController = UIAlertController(title: "GPRS is Required", message: "This app requires your location,please turn on your location service or set your address", preferredStyle: .alert)
let saveAction = UIAlertAction(title: "Set Address", style: UIAlertActionStyle.default, handler: {
alert -> Void in
// self.alertTogetAdrressFromUser()
})
alertController.addAction(saveAction)
let cancelAction = UIAlertAction(title: "Settings", style: UIAlertActionStyle.default, handler: {
(action : UIAlertAction!) -> Void in
// UIApplication.shared.openURL(NSURL(string: UIApplicationOpenSettingsURLString)! as URL)
})
alertController.addAction(cancelAction)
UIApplication.shared.keyWindow?.rootViewController?.present(alertController, animated: true, completion: nil)
}
}
My very first app is working fine so far, if location services are allowed for it.
As soon as I disable the location services for this app in particular (Airplane mode, as well as generally disabled location services are working as expected).
The code is the following:
func locationServices()->Bool{
if CLLocationManager.locationServicesEnabled() {
switch(CLLocationManager.authorizationStatus()) {
case .NotDetermined, .Restricted, .Denied:
return false
case .AuthorizedAlways, .AuthorizedWhenInUse:
return true
}
} else {
return false
}
}
Called from the viewDidLoad:
override func viewDidLoad() {
super.viewDidLoad()
txtNotes.delegate = self
datePicker.maximumDate = NSDate()
if (inc != nil) {
let Dateformatter = NSDateFormatter()
Dateformatter.dateStyle = NSDateFormatterStyle.MediumStyle
navigationItem.title = Dateformatter.stringFromDate((inc?.date)!)
datePicker.date = (inc?.date)!
txtNotes.text = inc?.notes
ratingControl.rating = (inc?.rating)!
lblAccuracy.text = inc?.geoloc
self.location = inc?.geocor
}
else {
if(locationServices()){
self.locationManager = CLLocationManager()
locationManager!.delegate = self
locationManager!.requestWhenInUseAuthorization()
locationManager!.desiredAccuracy = kCLLocationAccuracyBest
locationManager!.startUpdatingLocation()
}
else{
lblAccuracy.text = "Location Services Disabled"
let alertController = UIAlertController(
title: "Location Services Disabled",
message: "Please allow this application to use location services",
preferredStyle: .Alert)
let cancelAction = UIAlertAction(title: "Cancel", style: .Cancel, handler: nil)
alertController.addAction(cancelAction)
let openAction = UIAlertAction(title: "Open Settings", style: .Default) { (action) in
if let url = NSURL(string:UIApplicationOpenSettingsURLString) {
UIApplication.sharedApplication().openURL(url)
}
}
alertController.addAction(openAction)
self.presentViewController(alertController, animated: true, completion: nil)
viewDidLoad()
}
}
}
Accessing a not yet initialized delegate is not a smart idea...
Initializing prior to accessing it resolved my issue.
Hello i have multiple markers like this:
var Groningen = GMSMarker()
marker.position = CLLocationCoordinate2DMake(...., .....)
marker.title = "...."
marker.icon = UIImage(named: "...")
marker.snippet = "....."
marker.map = mapView
var marker1= GMSMarker()
marker1.position = CLLocationCoordinate2DMake(...., .....)
marker1.title = "...."
marker1.icon = UIImage(named: "...")
marker1.snippet = "....."
marker1.map = mapView
In want to add a button in the InfoWindow or in a label below the map that will set directions from the current location to de selected marker.
When the user click on the button its get question like this:
func mapView(mapView: GMSMapView!, didTapInfoWindowOfMarker marker: GMSMarker!) {
let actionSheetController: UIAlertController = UIAlertController(title: "Navigeer", message: "Kies een optie!", preferredStyle: .ActionSheet)
//Create and add the Cancel action
let cancelAction: UIAlertAction = UIAlertAction(title: "Cancel", style: .Cancel) { action -> Void in
//Do some stuff
}
actionSheetController.addAction(cancelAction)
//Create and add first option action
let GoGoogleMaps: UIAlertAction = UIAlertAction(title: "Google Maps", style: .Default) { action -> Void in
if (UIApplication.sharedApplication().canOpenURL(NSURL(string:"comgooglemaps://")!)) {
UIApplication.sharedApplication().openURL(NSURL(string:
"comgooglemaps://?center=40.765819,-73.975866&zoom=14&views=traffic")!)
} else {
UIApplication.sharedApplication().openURL(NSURL(string:
"https://maps.google.com/?daddr=Amsterdam")!);
}
//Do some other stuff
}
actionSheetController.addAction(GoGoogleMaps)
//Create and add a second option action
let GoAppleMaps: UIAlertAction = UIAlertAction(title: "Apple Maps", style: .Default) { action -> Void in
if (UIApplication.sharedApplication().canOpenURL(NSURL(string:"http://maps.apple.com")!)) {
UIApplication.sharedApplication().openURL(NSURL(string:
"http://maps.apple.com/?daddr=Amsterdam")!)
} else {
NSLog("Can't use Apple Maps");
}
//Do some other stuff
}
actionSheetController.addAction(GoAppleMaps)
//We need to provide a popover sourceView when using it on iPad
actionSheetController.popoverPresentationController?.sourceView = sender as! UIView;
//Present the AlertController
self.presentViewController(actionSheetController, animated: true, completion: nil)
}
Is this possible in a way.
Based on this Stackoverflow answer, there is no easy way to add a touch event on a button in custom info window.
(You could instead implement GMSMapViewDelegate's -didTapInfoWindowOfMarker: delegate method to check if the infowindow was tapped.
(the drawback is that the entire infowindow becomes one button))
But if you want to add an UILabel in your MapView, you need to set the consumesGesturesInView to be false. So the UILabel can receive touch events.
Sample Code of adding an UILabel with touch event:
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
let label = UILabel(frame: CGRectMake(view.frame.size.width - 100, view.frame.size.height - 40, 80, 30))
label.backgroundColor = UIColor.whiteColor()
label.text = "direction"
label.textAlignment = .Center
label.layer.cornerRadius = 10
label.clipsToBounds = true
label.userInteractionEnabled = true
let tap = UITapGestureRecognizer(target: self, action: "directionTapped")
label.addGestureRecognizer(tap)
mapView!.settings.consumesGesturesInView = false
mapView!.addSubview(label)
mapView!.bringSubviewToFront(label)
}
Sample Code of showing Maps direction options:
func directionTapped() {
let openMapsActionSheet = UIAlertController(title: "Open in Maps", message: "Choose a maps application", preferredStyle: .ActionSheet)
openMapsActionSheet.addAction(UIAlertAction(title: "Apple Maps", style: .Default, handler: { (action: UIAlertAction!) -> Void in
let placemark = MKPlacemark(coordinate: CLLocationCoordinate2DMake(self.mapView!.selectedMarker.position.latitude, self.mapView!.selectedMarker.position.longitude), addressDictionary: nil)
let item = MKMapItem(placemark: placemark)
let options = [MKLaunchOptionsDirectionsModeKey:
MKLaunchOptionsDirectionsModeDriving,
MKLaunchOptionsShowsTrafficKey: true]
item.openInMapsWithLaunchOptions(options as [NSObject : AnyObject])
}))
openMapsActionSheet.addAction(UIAlertAction(title: "Google Maps", style: .Default, handler: { (action: UIAlertAction!) -> Void in
if (UIApplication.sharedApplication().canOpenURL(NSURL(string:"comgooglemaps://")!)) {
UIApplication.sharedApplication().openURL(NSURL(string:
"comgooglemaps://?saddr=\(self.mapView!.selectedMarker.position.latitude),\(self.mapView!.selectedMarker.position.longitude)&daddr=\(self.mapView!.selectedMarker.position.latitude),\(self.mapView!.selectedMarker.position.longitude)")!)
} else {
UIApplication.sharedApplication().openURL(NSURL(string:
"http://maps.google.com/maps?saddr=\(self.mapView!.selectedMarker.position.latitude),\(self.mapView!.selectedMarker.position.longitude)&daddr=\(self.mapView!.selectedMarker.position.latitude),\(self.mapView!.selectedMarker.position.longitude)")!)
}
}))
openMapsActionSheet.addAction(UIAlertAction(title: "Cancel", style: .Cancel, handler: nil))
presentViewController(openMapsActionSheet, animated: true, completion: nil)
}