SWIFT 4,发布带有方向的地图应用程序

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (14)

我已经在网上搜索了很多,但解释/示例要么不起作用,要么严重过时。

情况:我有一张带有一些自定义注释的地图。单击注释时,按钮旁边会出现标题和副标题。当我点击该按钮时,它应该启动地图应用程序,并给我从用户位置到自定义引脚注释的指示。

我的问题是,当我单击按钮时,我的应用程序崩溃或没有任何反应。

这是我的代码:

import UIKit
import MapKit
import CoreLocation

class customPin: NSObject, MKAnnotation {
    var coordinate: CLLocationCoordinate2D
    var title: String?
    var subtitle: String?

    init(pinTitle:String, pinSubTitle:String, location:CLLocationCoordinate2D) {
        self.title = pinTitle
        self.subtitle = pinSubTitle
        self.coordinate = location
    }
}
class ViewController: UIViewController, MKMapViewDelegate {

    var selectedPin:MKPlacemark? = nil

    let locationManager = CLLocationManager()

    @IBOutlet weak var mapView: MKMapView!


    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        self.mapView.delegate = self
        locationManager.delegate = self
        locationManager.requestWhenInUseAuthorization()
        locationManager.startUpdatingLocation()
        mapView.showsUserLocation = true

        NotificationCenter.default.addObserver(self,
                                               selector: #selector(self.applicationDidResignActive),
                                               name: Notification.Name.UIApplicationWillResignActive,
                                               object: nil)

        //mapView.setRegion(MKCoordinateRegionMakeWithDistance(CLLocationCoordinate2DMake(62.524459, 6.630952 ), 955000, 955000), animated: true)


        // add annotations
        //PART 1
        let location = CLLocationCoordinate2DMake(62.524459, 6.630952)
        let location2 = CLLocationCoordinate2DMake(62.622460, 7.009174 )
        let location3 = CLLocationCoordinate2DMake(62.491195, 6.606216 )


        //PART 2
        let pin = customPin(pinTitle: "Bunker Oil Stette, 6265",
                            pinSubTitle:"Bensin",
                            location:location)
        let pin2 = customPin(pinTitle: "Bensin" ,
                             pinSubTitle:"Shit",
                             location:location2)
        let pin3 = customPin(pinTitle: "Shit" , pinSubTitle:"Adres35", location:location3)




        //PART 3
        mapView.addAnnotation(pin)
        mapView.addAnnotation(pin2)
        mapView.addAnnotation(pin3)


    }

    @objc func applicationDidResignActive(notification: NSNotification) {
        // handle event
    }

    @objc func getDirections(){
        guard let selectedPin = selectedPin else { return }
        let mapItem = MKMapItem(placemark: selectedPin)
        let launchOptions = [MKLaunchOptionsDirectionsModeKey: MKLaunchOptionsDirectionsModeDriving]
        mapItem.openInMaps(launchOptions: launchOptions)
        print ("GET DIRECTION")
    }

    /*func getDirections(){
        if let selectedPin = selectedPin {
            let mapItem = MKMapItem(placemark: selectedPin)
            let launchOptions = [MKLaunchOptionsDirectionsModeKey : MKLaunchOptionsDirectionsModeDriving]
            mapItem.openInMaps(launchOptions: launchOptions)
        } */


    func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
        if annotation is MKUserLocation {
            return nil
        }

        let annotationView = MKAnnotationView(annotation: annotation, reuseIdentifier: "customannotation")


        if annotation.subtitle == "Bensin" {
            annotationView.image = UIImage(named:"rBluepin")
        } else if annotation.subtitle == "Shit" {
            annotationView.image = UIImage(named:"rPurple")

        } else {

        annotationView.image = UIImage(named:"darkgreenpin")
        }
        // ------ UI BUTTON -----
        let image1 = UIImage(named: "rRedpin")!
        // in case you don't want image to change when "clicked", you can leave code below


        let rightButton = UIButton(type: .contactAdd)
        rightButton.tag = annotation.hash
        rightButton.setImage(image1, for: UIControlState.normal)



        //annotationView.animatesDrop = true
        annotationView.canShowCallout = true
        annotationView.rightCalloutAccessoryView = rightButton


        // ---- GET DIRECTIONS

        //let launchOptions = [MKLaunchOptionsDirectionsModeKey : MKLaunchOptionsDirectionsModeDriving]
        //let mapItem = MKMapItem(placemark: annotation as! MKPlacemark)
        //let launchOptions = [MKLaunchOptionsDirectionsModeKey : MKLaunchOptionsDirectionsModeDriving]
        //mapItem.openInMaps(launchOptions: launchOptions)


        //rightButton.setBackgroundImage(UIImage(named: "rRedpin"), for: .normal)
        //rightButton.addTarget(self, action: Selector(("getDirections")), for: .touchUpInside)
        rightButton.addTarget(self, action: #selector(ViewController.getDirections), for: .touchUpInside)
        annotationView.leftCalloutAccessoryView = rightButton

        annotationView.canShowCallout = true
        return annotationView
    }

    func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) {
        print("annotation title == \(String(describing: view.annotation?.title!))")
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    }

    extension ViewController : CLLocationManagerDelegate {

    private func locationManager(  manager: CLLocationManager, didChangeAuthorizationStatus status: CLAuthorizationStatus) {
        if status == .authorizedWhenInUse {
            locationManager.requestLocation()
        }
    }

    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        guard let location = locations.first else { return }
        let span = MKCoordinateSpanMake(1.120, 1.120)
        let region = MKCoordinateRegion(center: location.coordinate, span: span)
        mapView.setRegion(region, animated: true)
    }

    func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
        print("error:: \(error)")
    }
}

我想我非常接近在地图中发布方向。我没有得到当前代码的任何错误。

模拟器的屏幕截图 - > 模拟器的屏幕截图

感谢帮助!

提问于
用户回答回答于

您的getDirections代码依赖于实例属性selectedPin,声明如下:

var selectedPin:MKPlacemark? = nil

你所展示的代码都没有设置过 selectedPin,所以没有任何代码可以改变它nil。因此,当你说(在开始时getDirections):

guard let selectedPin = selectedPin else { return }

......我期待着我们return,没有任何事情发生。

(我已经解释过“没有任何反应”。我不知道为什么你的应用程序会崩溃,但是你在问题上有责任提供崩溃日志或其他有关崩溃的信息,所以我不负责跟踪也许崩溃来自你添加guard let声明之前的时间?)

热门问答

SCF 服务中运行 puppeteer 缺少中文字体?

推荐已采纳

您好,这个功能正在发布中,烦请持续关注~

腾讯云通信SDK接入问题?

人生的旅途辣鸡前端
推荐
您好,为了进一步优化管理通知,Google在发布android 8 时对通知做了修改优化,出现了通知渠道功能。具体可以参考以下文章: https://www.jianshu.com/p/8baa62c5bfc2 如有其它异常,可联系QQ3268519604 感谢您对云通信的支持与...... 展开详请

急急急!!核验图片验证码填写到接入备案企业侧备案系统中,在哪操作啊?

无聊至极互联网重度用户
推荐
你反馈的上海备案的APP核验验证码吗?如果是的话,提交订单的时候直接写验证码就可以的。 在补充材料的下面 image.png ... 展开详请

存储桶和项目概念?

Hyman.W

腾讯云 · 高级产品经理 (已认证)

推荐
一个存储桶对应多个项目的管理方式,可以使用 “标签” 来管理, 在创建存储桶或者修改存储桶配置的页面可以添加。 参考: 1,存储桶标签使用 https://cloud.tencent.com/document/product/436/34830 2,如果需要通过外部系统来管理...... 展开详请

智能钛能处理大数据文件吗?我有30G的数据存储在本地电脑硬盘上?

腾讯智能钛AI开发者

腾讯云 · 智能钛产品团队 (已认证)

腾讯智能钛产品团队官方运营账号。分享产品最新动态,第一时间解答用户疑问。
推荐

硬盘可以升级吗?

最爱开车啦互联网的敏感者
推荐

可以升级,小微活动中没有云硬盘的的,后续可以用同帐号在官网购买和服务器同地域同地区的云硬盘挂载到服务器上使用。

云硬盘挂载初始化方法 可参考 https://cloud.tencent.com/document/product/362/6735

所属标签

扫码关注云+社区

领取腾讯云代金券