地图视图:GMSMapView!零导致应用程序崩溃 (swift)
mapView: GMSMapView! nil causing the app to crash (swift)
对于 iOS 使用 Google Maps SKD 我是个新手,我遇到以下问题:我的应用程序使用 Firebase,而 MapVC 是第一个VC 如果用户已登录。我在情节提要中设置了一个 UIVIew,其大小为我想要的,并制作了 class GMSMapView。我还使用 CLLocation 管理器并且位置正常,我将它传递给相机变量并且没问题。但是如果添加此代码:mapView = GMSMapView.map(withFrame: CGRect.zero, camera: camera)
或此代码:self.mapView.camera = camera
应用程序崩溃,因为 mapView 为零。如果我不添加这些代码行,则显示的地图只是默认地图(欧洲)。我需要的是地图相机来显示我从 CLLocation 获得的位置,并随着位置的变化在地图上更新它。
我的地图代码VC如下:
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")
}
}
}
}
如果有任何帮助,我将不胜感激。谢谢=)
如果您在情节提要中创建了 'View' 并分配为 'GMSMapView',您应该将其添加为 'IBOutlet' 到 ViewController,您可以通过单击 'Option' 并从地图拖动到 ViewController 就像你添加 'alertaBtn' 一样,如果你想以编程方式创建地图你需要在 'viewDidLoad' 方法中启动它然后使用它来设置相机或进行其他更改。
对于 iOS 使用 Google Maps SKD 我是个新手,我遇到以下问题:我的应用程序使用 Firebase,而 MapVC 是第一个VC 如果用户已登录。我在情节提要中设置了一个 UIVIew,其大小为我想要的,并制作了 class GMSMapView。我还使用 CLLocation 管理器并且位置正常,我将它传递给相机变量并且没问题。但是如果添加此代码:mapView = GMSMapView.map(withFrame: CGRect.zero, camera: camera)
或此代码:self.mapView.camera = camera
应用程序崩溃,因为 mapView 为零。如果我不添加这些代码行,则显示的地图只是默认地图(欧洲)。我需要的是地图相机来显示我从 CLLocation 获得的位置,并随着位置的变化在地图上更新它。
我的地图代码VC如下:
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")
}
}
}
}
如果有任何帮助,我将不胜感激。谢谢=)
如果您在情节提要中创建了 'View' 并分配为 'GMSMapView',您应该将其添加为 'IBOutlet' 到 ViewController,您可以通过单击 'Option' 并从地图拖动到 ViewController 就像你添加 'alertaBtn' 一样,如果你想以编程方式创建地图你需要在 'viewDidLoad' 方法中启动它然后使用它来设置相机或进行其他更改。