diff --git a/README.md b/README.md
index b8e459f52..ed136f9be 100644
--- a/README.md
+++ b/README.md
@@ -24,8 +24,10 @@ This project uses Mapbox vector tiles, which requires a Mapbox account and a Map
After you get the key, place it in project's Android directory:
- Add your access token to `$project_dir/example/android/app/src/values/developer-config.xml`
-##### iOS
-Add this lines to your Info.plist
+
+#### iOS
+Add these lines to your Info.plist
+
```plist
io.flutter.embedded_views_preview
diff --git a/ios/Classes/Convert.swift b/ios/Classes/Convert.swift
index 858191ff9..9e08775db 100644
--- a/ios/Classes/Convert.swift
+++ b/ios/Classes/Convert.swift
@@ -34,4 +34,90 @@ class Convert {
delegate.setMyLocationEnabled(myLocationEnabled: myLocationEnabled)
}
}
+
+ class func parseCameraUpdate(cameraUpdate: [Any], mapView: MGLMapView) -> MGLMapCamera? {
+ guard let type = cameraUpdate[0] as? String else { return nil }
+ switch (type) {
+ case "newCameraPosition":
+ guard let cameraPosition = cameraUpdate[1] as? [String: Any] else { return nil }
+ return MGLMapCamera.fromDict(cameraPosition, mapView: mapView)
+ case "newLatLng":
+ guard let coordinate = cameraUpdate[1] as? [Double] else { return nil }
+ let camera = mapView.camera
+ camera.centerCoordinate = CLLocationCoordinate2D.fromArray(coordinate)
+ return camera
+ case "newLatLngBounds":
+ guard let bounds = cameraUpdate[1] as? [[Double]] else { return nil }
+ guard let padding = cameraUpdate[2] as? CGFloat else { return nil }
+ return mapView.cameraThatFitsCoordinateBounds(MGLCoordinateBounds.fromArray(bounds), edgePadding: UIEdgeInsets.init(top: padding, left: padding, bottom: padding, right: padding))
+ case "newLatLngZoom":
+ guard let coordinate = cameraUpdate[1] as? [Double] else { return nil }
+ guard let zoom = cameraUpdate[2] as? Double else { return nil }
+ let camera = mapView.camera
+ camera.centerCoordinate = CLLocationCoordinate2D.fromArray(coordinate)
+ let altitude = getAltitude(zoom: zoom, mapView: mapView)
+ return MGLMapCamera(lookingAtCenter: camera.centerCoordinate, altitude: altitude, pitch: camera.pitch, heading: camera.heading)
+ case "scrollBy":
+ guard let x = cameraUpdate[1] as? CGFloat else { return nil }
+ guard let y = cameraUpdate[2] as? CGFloat else { return nil }
+ let camera = mapView.camera
+ let mapPoint = mapView.convert(camera.centerCoordinate, toPointTo: mapView)
+ let movedPoint = CGPoint(x: mapPoint.x + x, y: mapPoint.y + y)
+ camera.centerCoordinate = mapView.convert(movedPoint, toCoordinateFrom: mapView)
+ return camera
+ case "zoomBy":
+ guard let zoomBy = cameraUpdate[1] as? Double else { return nil }
+ let camera = mapView.camera
+ let zoom = getZoom(mapView: mapView)
+ let altitude = getAltitude(zoom: zoom+zoomBy, mapView: mapView)
+ camera.altitude = altitude
+ if (cameraUpdate.count == 2) {
+ return camera
+ } else {
+ guard let point = cameraUpdate[2] as? [CGFloat], point.count == 2 else { return nil }
+ let movedPoint = CGPoint(x: point[0], y: point[1])
+ camera.centerCoordinate = mapView.convert(movedPoint, toCoordinateFrom: mapView)
+ return camera
+ }
+ case "zoomIn":
+ let camera = mapView.camera
+ let zoom = getZoom(mapView: mapView)
+ let altitude = getAltitude(zoom: zoom + 1, mapView: mapView)
+ camera.altitude = altitude
+ return camera
+ case "zoomOut":
+ let camera = mapView.camera
+ let zoom = getZoom(mapView: mapView)
+ let altitude = getAltitude(zoom: zoom - 1, mapView: mapView)
+ camera.altitude = altitude
+ return camera
+ case "zoomTo":
+ guard let zoom = cameraUpdate[1] as? Double else { return nil }
+ let camera = mapView.camera
+ let altitude = getAltitude(zoom: zoom, mapView: mapView)
+ camera.altitude = altitude
+ return camera
+ case "bearingTo":
+ guard let bearing = cameraUpdate[1] as? Double else { return nil }
+ let camera = mapView.camera
+ camera.heading = bearing
+ return camera
+ case "tiltTo":
+ guard let tilt = cameraUpdate[1] as? CGFloat else { return nil }
+ let camera = mapView.camera
+ camera.pitch = tilt
+ return camera
+ default:
+ print("\(type) not implemented!")
+ }
+ return nil
+ }
+
+ class func getZoom(mapView: MGLMapView) -> Double {
+ return MGLZoomLevelForAltitude(mapView.camera.altitude, mapView.camera.pitch, mapView.camera.centerCoordinate.latitude, mapView.frame.size)
+ }
+
+ class func getAltitude(zoom: Double, mapView: MGLMapView) -> Double {
+ return MGLAltitudeForZoomLevel(zoom, mapView.camera.pitch, mapView.camera.centerCoordinate.latitude, mapView.frame.size)
+ }
}
diff --git a/ios/Classes/MapboxMapController.swift b/ios/Classes/MapboxMapController.swift
index ac2507484..2ba4b0a4e 100644
--- a/ios/Classes/MapboxMapController.swift
+++ b/ios/Classes/MapboxMapController.swift
@@ -55,6 +55,18 @@ class MapboxMapController: NSObject, FlutterPlatformView, MGLMapViewDelegate, Ma
} else {
result(nil)
}
+ case "camera#move":
+ guard let arguments = methodCall.arguments as? [String: Any] else { return }
+ guard let cameraUpdate = arguments["cameraUpdate"] as? [Any] else { return }
+ if let camera = Convert.parseCameraUpdate(cameraUpdate: cameraUpdate, mapView: mapView) {
+ mapView.setCamera(camera, animated: false)
+ }
+ case "camera#animate":
+ guard let arguments = methodCall.arguments as? [String: Any] else { return }
+ guard let cameraUpdate = arguments["cameraUpdate"] as? [Any] else { return }
+ if let camera = Convert.parseCameraUpdate(cameraUpdate: cameraUpdate, mapView: mapView) {
+ mapView.setCamera(camera, animated: true)
+ }
default:
result(FlutterMethodNotImplemented)
}