我有几个显示地图的ViewController,所以我将常见的地图逻辑提取到MapViewController
中:
import UIKit
import GoogleMaps
import GooglePlaces
class MapViewController : UIViewController {
var locationService: CLLocationManager!
var placesClient: GMSPlacesClient!
var marker: GMSMarker!
var camera: GMSCameraPosition!
var animatedMarkerImage: UIImage!
var markerImage1: UIImage!
var markerImage2: UIImage!
var markerImage3: UIImage!
var markerImage4: UIImage!
var markerImages: [UIImage]!
@IBOutlet weak var mapView: GMSMapView!
override func viewDidLoad() {
super.viewDidLoad()
locationService = LocationService.shared
placesClient = GMSPlacesClient.shared()
markerImage1 = UIImage(named: "Location 01@3x")
markerImage2 = UIImage(named: "Location 02@3x")
markerImage3 = UIImage(named: "Location 03@3x")
markerImage4 = UIImage(named: "Location 04v@3x")
markerImages = [markerImage1, markerImage2, markerImage3, markerImage4]
animatedMarkerImage = UIImage.animatedImage(with: markerImages, duration: 1.5)
do {
if let styleURL = Bundle.main.url(forResource: "mapStyle", withExtension: "json") {
mapView.mapStyle = try GMSMapStyle(contentsOfFileURL: styleURL)
} else {
NSLog("Unable to find mapStyle.json")
}
} catch {
NSLog("One or more of the map styles failed to load. \(error)")
}
}
}
extension MapViewController : CLLocationManagerDelegate {
func startReceivingLocationChanges() {
let authorizationStatus = CLLocationManager.authorizationStatus()
if authorizationStatus != .authorizedWhenInUse && authorizationStatus != .authorizedAlways {
return
}
if !CLLocationManager.locationServicesEnabled() {
return
}
locationService.desiredAccuracy = kCLLocationAccuracyHundredMeters
locationService.distanceFilter = 100.0
locationService.startUpdatingLocation()
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let location = locations.last!
if marker == nil {
camera = GMSCameraPosition.camera(withLatitude: location.coordinate.latitude, longitude: location.coordinate.longitude, zoom: 14.0)
marker = GMSMarker()
let markerView = UIImageView(image: animatedMarkerImage)
marker.position = CLLocationCoordinate2D(latitude: location.coordinate.latitude, longitude: location.coordinate.longitude)
marker.iconView = markerView
marker.map = mapView
marker.appearAnimation = GMSMarkerAnimation.pop
mapView.camera = camera
} else {
CATransaction.begin()
CATransaction.setAnimationDuration(1.0)
marker.position = location.coordinate
CATransaction.commit()
}
}
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
if let error = error as? CLError, error.code == .denied {
manager.stopUpdatingLocation()
return
}
print("Location error: \(error)")
}
}
我有三个不同的ViewController,它们从此MapViewController继承并按如下方式覆盖每个viewDidLoad()
:
override func viewDidLoad() {
super.viewDidLoad()
locationService.delegate = self
startReceivingLocationChanges()
}
地图和标记会正确显示,并且相机会移动到第一个ViewController的正确位置,但是从MapViewController继承的任何后续ViewController只会显示UK。
在func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation])
中放置一个断点表明第一个ViewController接收了更新的位置,但随后的ViewController没有。
有人可以告诉我我在做什么错吗?
答案 0 :(得分:1)
由于Schedule
Cron expression 0 12 ? * 2 *
Next 10 Trigger Date(s)
Mon, 29 Oct 2018 12:00:00 GMT
Mon, 05 Nov 2018 12:00:00 GMT
Mon, 12 Nov 2018 12:00:00 GMT
Mon, 19 Nov 2018 12:00:00 GMT
Mon, 26 Nov 2018 12:00:00 GMT
Mon, 03 Dec 2018 12:00:00 GMT
Mon, 10 Dec 2018 12:00:00 GMT
Mon, 17 Dec 2018 12:00:00 GMT
Mon, 24 Dec 2018 12:00:00 GMT
Mon, 31 Dec 2018 12:00:00 GMT
公开了LocationService
的一个实例。 CLLocationManager
被分配给最后一个要加载的viewController。这就是为什么其他viewController不接收更新的原因。我将使delegate
符合LocationService
并将其委托给它自己。然后将CLLocationDelegate
函数添加到updateLocation
来处理地图更新。
MapViewController
在您的func updateLocation(location: CLLocation){
if marker == nil {
camera = GMSCameraPosition.camera(withLatitude: location.coordinate.latitude, longitude: location.coordinate.longitude, zoom: 14.0)
marker = GMSMarker()
let markerView = UIImageView(image: animatedMarkerImage)
marker.position = CLLocationCoordinate2D(latitude: location.coordinate.latitude, longitude: location.coordinate.longitude)
marker.iconView = markerView
marker.map = mapView
marker.appearAnimation = GMSMarkerAnimation.pop
mapView.camera = camera
} else {
CATransaction.begin()
CATransaction.setAnimationDuration(1.0)
marker.position = location.coordinate
CATransaction.commit()
}
}
中,通过调用LocationService
updateLocation
执行此操作的另一种方法是给每个func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let location = locations.last!
viewController1.updateLocation(location: location)
viewController2.updateLocation(location: location)
viewController3.updateLocation(location: location)
}
一个不同的MapViewController
实例(不共享),但这不能实现重用的想法。 CLLocationManager
正在访问设备上的单个位置服务时,CLLocationManager
的每个实例将执行相同的工作3次。希望这会有所帮助。