summaryrefslogtreecommitdiff
path: root/platform/ios/demo/Examples/Swift/DraggableAnnotationViewExample.swift
diff options
context:
space:
mode:
Diffstat (limited to 'platform/ios/demo/Examples/Swift/DraggableAnnotationViewExample.swift')
-rw-r--r--platform/ios/demo/Examples/Swift/DraggableAnnotationViewExample.swift127
1 files changed, 127 insertions, 0 deletions
diff --git a/platform/ios/demo/Examples/Swift/DraggableAnnotationViewExample.swift b/platform/ios/demo/Examples/Swift/DraggableAnnotationViewExample.swift
new file mode 100644
index 0000000000..54d4fa6a06
--- /dev/null
+++ b/platform/ios/demo/Examples/Swift/DraggableAnnotationViewExample.swift
@@ -0,0 +1,127 @@
+import Mapbox
+
+@objc(DraggableAnnotationViewExample_Swift)
+
+// Example view controller
+class DraggableAnnotationViewExample_Swift: UIViewController, MGLMapViewDelegate {
+ override func viewDidLoad() {
+ super.viewDidLoad()
+
+ let mapView = MGLMapView(frame: view.bounds)
+ mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
+ mapView.styleURL = MGLStyle.lightStyleURL(withVersion: 9)
+ mapView.tintColor = .darkGray
+ mapView.zoomLevel = 1
+ mapView.delegate = self
+ view.addSubview(mapView)
+
+ // Specify coordinates for our annotations.
+ let coordinates = [
+ CLLocationCoordinate2D(latitude: 0, longitude: -70),
+ CLLocationCoordinate2D(latitude: 0, longitude: -35),
+ CLLocationCoordinate2D(latitude: 0, longitude: 0),
+ CLLocationCoordinate2D(latitude: 0, longitude: 35),
+ CLLocationCoordinate2D(latitude: 0, longitude: 70)
+ ]
+
+ // Fill an array with point annotations and add it to the map.
+ var pointAnnotations = [MGLPointAnnotation]()
+ for coordinate in coordinates {
+ let point = MGLPointAnnotation()
+ point.coordinate = coordinate
+ point.title = "To drag this annotation, first tap and hold."
+ pointAnnotations.append(point)
+ }
+
+ mapView.addAnnotations(pointAnnotations)
+ }
+
+ // MARK: - MGLMapViewDelegate methods
+
+ // This delegate method is where you tell the map to load a view for a specific annotation. To load a static MGLAnnotationImage, you would use `-mapView:imageForAnnotation:`.
+ func mapView(_ mapView: MGLMapView, viewFor annotation: MGLAnnotation) -> MGLAnnotationView? {
+ // This example is only concerned with point annotations.
+ guard annotation is MGLPointAnnotation else {
+ return nil
+ }
+
+ // For better performance, always try to reuse existing annotations. To use multiple different annotation views, change the reuse identifier for each.
+ if let annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: "draggablePoint") {
+ return annotationView
+ } else {
+ return DraggableAnnotationView(reuseIdentifier: "draggablePoint", size: 50)
+ }
+ }
+
+ func mapView(_ mapView: MGLMapView, annotationCanShowCallout annotation: MGLAnnotation) -> Bool {
+ return true
+ }
+}
+
+// MGLAnnotationView subclass
+class DraggableAnnotationView: MGLAnnotationView {
+ init(reuseIdentifier: String, size: CGFloat) {
+ super.init(reuseIdentifier: reuseIdentifier)
+
+ // `isDraggable` is a property of MGLAnnotationView, disabled by default.
+ isDraggable = true
+
+ // This property prevents the annotation from changing size when the map is tilted.
+ scalesWithViewingDistance = false
+
+ // Begin setting up the view.
+ frame = CGRect(x: 0, y: 0, width: size, height: size)
+
+ backgroundColor = .darkGray
+
+ // Use CALayer’s corner radius to turn this view into a circle.
+ layer.cornerRadius = size / 2
+ layer.borderWidth = 1
+ layer.borderColor = UIColor.white.cgColor
+ layer.shadowColor = UIColor.black.cgColor
+ layer.shadowOpacity = 0.1
+ }
+
+ // These two initializers are forced upon us by Swift.
+ override init(frame: CGRect) {
+ super.init(frame: frame)
+ }
+
+ required init?(coder aDecoder: NSCoder) {
+ fatalError("init(coder:) has not been implemented")
+ }
+
+ // Custom handler for changes in the annotation’s drag state.
+ override func setDragState(_ dragState: MGLAnnotationViewDragState, animated: Bool) {
+ super.setDragState(dragState, animated: animated)
+
+ switch dragState {
+ case .starting:
+ print("Starting", terminator: "")
+ startDragging()
+ case .dragging:
+ print(".", terminator: "")
+ case .ending, .canceling:
+ print("Ending")
+ endDragging()
+ case .none:
+ return
+ }
+ }
+
+ // When the user interacts with an annotation, animate opacity and scale changes.
+ func startDragging() {
+ UIView.animate(withDuration: 0.3, delay: 0, usingSpringWithDamping: 0.5, initialSpringVelocity: 0, options: [], animations: {
+ self.layer.opacity = 0.8
+ self.transform = CGAffineTransform.identity.scaledBy(x: 1.5, y: 1.5)
+ }, completion: nil)
+ }
+
+ func endDragging() {
+ transform = CGAffineTransform.identity.scaledBy(x: 1.5, y: 1.5)
+ UIView.animate(withDuration: 0.3, delay: 0, usingSpringWithDamping: 0.5, initialSpringVelocity: 0, options: [], animations: {
+ self.layer.opacity = 1
+ self.transform = CGAffineTransform.identity.scaledBy(x: 1, y: 1)
+ }, completion: nil)
+ }
+}