diff options
Diffstat (limited to 'platform/ios/demo/Examples/Swift/DraggableAnnotationViewExample.swift')
-rw-r--r-- | platform/ios/demo/Examples/Swift/DraggableAnnotationViewExample.swift | 127 |
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) + } +} |