我的应用在尝试设置地图视图时崩溃

时间:2017-05-05 01:08:29

标签: ios swift google-maps storyboard

我正在尝试将风格化的Google地图集成到我正在使用Swift编程的iOS应用中。我的故事板中有一个GMSMapView视图,我正在尝试使用自定义JSON对其进行着色。这是制作mapView的代码:

@IBOutlet weak var mapView: GMSMapView!

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
    let userLocation = locations.last
    //let center = CLLocationCoordinate2D(latitude: userLocation!.coordinate.latitude, longitude: userLocation!.coordinate.longitude)

    let camera = GMSCameraPosition.camera(withLatitude: userLocation!.coordinate.latitude,
                                          longitude: userLocation!.coordinate.longitude, zoom: 13.0)

    mapView.isMyLocationEnabled = true
    mapView.camera = camera
    self.view = mapView

    locationManager.stopUpdatingLocation()
}

override func loadView() {
    do {
        // Set the map style by passing the URL of the local file.
        if let styleURL = Bundle.main.url(forResource: "style", withExtension: "json") {
***error->            self.mapView.mapStyle = try GMSMapStyle(contentsOfFileURL: styleURL)
        } else {
            NSLog("Unable to find style.json")
        }
    } catch {
        NSLog("One or more of the map styles failed to load. \(error)")
    }
}

但是当我尝试运行它时,我收到致命错误

  

在解包可选值时意外发现nil

抛出错误的行是***上的行。我已经将GMSMapView与故事板上的View相关联,并且应用程序正确编译而无需尝试设置样式。有谁知道为什么会出现这个错误?我用Google搜索了错误但找不到与我的代码有关的任何内容,我无法理解某些链接要我做的事情。

1 个答案:

答案 0 :(得分:2)

错误是因为self.mapViewnil。这就是原因:

您的地图视图已设置为故事板的插座。在这种情况下,将为您创建地图视图。只需确保地图视图实际连接到插座。

真正的问题是你已经重载了loadView方法。不要这样做。来自UIViewController loadView的文档:

  

如果使用Interface Builder创建视图并初始化视图控制器,则不得覆盖此方法。

loadView目前的代码应移至viewDidLoad方法。

override func viewDidLoad() {
    super.viewDidLoad()

    do {
        // Set the map style by passing the URL of the local file.
        if let styleURL = Bundle.main.url(forResource: "style", withExtension: "json") {
            self.mapView.mapStyle = try GMSMapStyle(contentsOfFileURL: styleURL)
        } else {
            NSLog("Unable to find style.json")
        }
    } catch {
        NSLog("One or more of the map styles failed to load. \(error)")
    }

    // and any other code you might need in viewDidLoad
}

下一个重要问题是您在位置管理器代理中为self.view分配了一个值。这也很糟糕。您应该在视图控制器中为self.view分配内容的唯一位置是loadView,并且仅当您以编程方式创建整个视图控制器及其视图时。

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
    let userLocation = locations.last
    //let center = CLLocationCoordinate2D(latitude: userLocation!.coordinate.latitude, longitude: userLocation!.coordinate.longitude)

    let camera = GMSCameraPosition.camera(withLatitude: userLocation!.coordinate.latitude,
                                          longitude: userLocation!.coordinate.longitude, zoom: 13.0)

    mapView.isMyLocationEnabled = true
    mapView.camera = camera

    locationManager.stopUpdatingLocation()
}

要点:

  1. 删除loadView方法。将其内容移至viewDidLoad
  2. 不要在代码中的任何位置分配self.view
  3. 确保故事板中的地图视图确实与您的插座连接。