ios - 地图视图:GMSMapView!nil 导致应用程序崩溃(迅速)
问题描述
在使用适用于 iOS 的 Google Maps SKD 时,我是全新的,我有以下问题:我的应用程序使用 Firebase,如果用户登录,MapVC 是第一个 VC。我在情节提要中设置了 UIVIew,其大小我想要并制作了它的类 GMSMapView。我还使用了 CLLocation 管理器,位置没问题,我将它传递给相机变量,这很好。但如果添加此代码: mapView = GMSMapView.map(withFrame: CGRect.zero, camera: camera)
或此代码:self.mapView.camera = camera
应用程序崩溃,因为 mapView 为 nil。如果我不添加这些代码行,则显示的地图只是默认地图(欧洲)。我需要的是地图相机来显示我从 CLLocation 获得的位置,并随着位置的变化在地图上更新它。
我的 MapVC 代码如下:
import UIKit
import GoogleMaps
import GooglePlaces
import CoreLocation
import Alamofire
import Firebase
import FirebaseFirestore
class AlertaVC: UIViewController, CLLocationManagerDelegate {
@IBOutlet weak var alertaBtn: RoundButton!
var latitude: CLLocationSpeed?
var longitude: CLLocationDegrees?
var mapView: GoogleMaps.GMSMapView!
var db: Firestore!
var userID: String?
var nameUser: Any?
let locationManager = CLLocationManager()
@IBAction func dispararAlertaBtn(_ sender: UIButton) {
//changing the title and color after the alert is sent
alertaBtn.isSelected = !alertaBtn.isSelected
if alertaBtn.isSelected {
//setting up twilio to send the alert SMS
let headers: HTTPHeaders = [
"Content-Type": "application/x-www-form-urlencoded"
]
//add the phone numbers from the firebase document
let parameters: Parameters = [
"To": "phone-number",
"Body": "Ola, to enviando SMS!"
]
//change the SMS body to include the user's name and the link with live location
AF.request("https://url.twil.io/smsAlerta", method: .post, parameters: parameters, headers: headers).responseJSON { response in
print(response.response as Any, "response alamofire")
}
alertaBtn.setTitle("Encerrar alerta!", for: .normal)
alertaBtn.backgroundColor = UIColor(red: 0.83529, green: 0.4, blue: 0.5725490196, alpha: 1.0)
} else {
alertaBtn.setTitle("Disparar alerta!", for: .normal)
alertaBtn.backgroundColor = UIColor(red: 0.3254, green: 0.1921, blue: 0.2627, alpha: 1.0)
}
}
override func viewDidLoad() {
super.viewDidLoad()
locationManager.requestAlwaysAuthorization()
locationManager.requestWhenInUseAuthorization()
if CLLocationManager.locationServicesEnabled() {
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
locationManager.startUpdatingLocation()
}
db = Firestore.firestore()
let user = Auth.auth().currentUser
if let user = user {
// The user's ID, unique to the Firebase project.
self.userID = user.uid
print(self.userID!, "user ID firebase")
}
}
override func viewWillAppear(_ animated: Bool) {
//showCurrentLocation() Tried calling the function @ViewWillAppear but it didn't work either
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
guard let locValue: CLLocationCoordinate2D = manager.location?.coordinate else { return }
latitude = locValue.latitude
longitude = locValue.longitude
let camera: GMSCameraPosition = GMSCameraPosition.camera(withLatitude: latitude ?? 19.741755, longitude: longitude ?? -155.844437, zoom: 7.0) //if doesnt load will show Hawaii
print(camera as Any, "camera") <-- WORKS FINE: GMSCameraPosition 0x600000f389f0: target:(37.332, -122.031) bearing:0.000 zoomLevel:7.000 viewingAngle:0.000 camera
self.mapView.camera = camera <<--- CRASHES HERE: Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value
self.mapView?.animate(to: camera) <<-- WITHOUT THE LINE ABOVE THIS ANIMATION DOESN`T HAPPEN, BECAUSE MAPVIEW IS NIL
print("locations = \(latitude ?? 56.56), \(longitude ?? 45.45)")
}
func showCurrentLocation() { <<- NOT BEING CALLED, BUT IF IT IS, CRASHES
//mapView.settings.myLocationButton = true
let locationObj = locationManager.location!
let coord = locationObj.coordinate
let lattitude = coord.latitude
let longitude = coord.longitude
print(" lat in updating \(lattitude) ")
print(" long in updating \(longitude)")
let center = CLLocationCoordinate2D(latitude: locationObj.coordinate.latitude, longitude: locationObj.coordinate.longitude)
let marker = GMSMarker()
marker.position = center
marker.title = "current location"
marker.map = mapView
let camera: GMSCameraPosition = GMSCameraPosition.camera(withLatitude: lattitude, longitude: longitude, zoom: 7.0)
mapView = GMSMapView.map(withFrame: CGRect.zero, camera: camera) <-- CRASHES HERE
self.mapView.animate(to: camera)
}
func fetchUserName(userId: String) {
db.collection("Usuarias").document(self.userID!).getDocument() {
(document, err) in
if let document = document, document.exists {
let dataDescription = document.data()!["Nome"] ?? "nil"
print("Document data: \(dataDescription)")
self.nameUser = dataDescription
print(self.nameUser as Any, "dentro do fetch")
} else {
print("Document does not exist")
}
}
}
}
我会很感激任何帮助。谢谢 =)
解决方案
如果您在情节提要中创建了“视图”并指定为“GMSMapView”,则应在 ViewController 中将其添加为“IBOutlet”,您可以通过单击键盘上的“选项”并从地图拖动到 ViewController 来完成,就像您添加“alertaBtn”,如果您想以编程方式创建地图,您需要在“viewDidLoad”方法中启动它,然后使用它来设置相机或进行其他更改。
推荐阅读
- ios - 无法在 RxSwift 中调用非函数类型错误的值?
- cordova - 使用 apache cordova 进行 USSD 调用
- solidity - solidity:从另一个合约调用函数时出错
- android - 根据搜索栏位置动态添加视图
- angular - Angular 5 - 将组件变量作为 Observable 类型有什么好处?
- ios - 如何在不重新启动应用程序的情况下以编程方式更改应用程序语言?
- python - 如何使用python或windows cmd控制静音电源SPD3303X
- android - 如何清除或删除 Here Maps Android Kotlin 上的路线
- javascript - 在嵌套子文档数组中查找与特定条件匹配的文档总数
- java - 仅更改用户的权限