summaryrefslogtreecommitdiff
path: root/platform/ios/Mapbox.playground
diff options
context:
space:
mode:
authorJesse Bounds <jesse@rebounds.net>2016-04-22 07:43:55 -0600
committerJesse Bounds <jesse@rebounds.net>2016-05-13 15:51:40 -0700
commit39669243b742a399818e5152c873ca71fa971648 (patch)
tree68f7828306b1c538052ad7c436979e4423edc77a /platform/ios/Mapbox.playground
parenta6ca18f23c0bff126507c5e038b789e7c125814a (diff)
downloadqtlocation-mapboxgl-39669243b742a399818e5152c873ca71fa971648.tar.gz
[ios] Introduce MGLAnnotationView and support for view annotations
Add an UIView subclass that can be used as the base class for all client provided UIViews for annotations. Teach MGLMapView to be able to display annotation views over the map if provided by the client delegate. For now, if the delegate provides a UIView then it will be used. If not, the map view will fall back to the old strategy of using GL annotations with an image provided by the delegate or a default image if not. The map keeps a reuse queue and will store annotation views that are panned offscreen in the queue if the application developer supplied a reuse queue identifer. The views in the queue are reused when more annotation views are required. This view reuse provides a performance gain when many annotations are shown and most of them are offscreen. iosapp now implements the new delegate method to supply a native view. Add a playground to the workspace to facilitate experimentation with new features. A playground is capable of importing frameworks if it exists in the same workspace that builds the imported framework. The initial playground demonstrates annotation views. This also fixes a crash due to nullptr in annotations array If the `annotations` method is called while the user dot's callout view was showing, the userdot annotation is represented as null in the annotation context map. This caused a crash when the null pointer was attempted to be converted into an NSArray via C array. This protects against this bug by filtering out such a null annotation.
Diffstat (limited to 'platform/ios/Mapbox.playground')
-rw-r--r--platform/ios/Mapbox.playground/Contents.swift133
-rw-r--r--platform/ios/Mapbox.playground/contents.xcplayground4
-rw-r--r--platform/ios/Mapbox.playground/timeline.xctimeline6
3 files changed, 143 insertions, 0 deletions
diff --git a/platform/ios/Mapbox.playground/Contents.swift b/platform/ios/Mapbox.playground/Contents.swift
new file mode 100644
index 0000000000..14dba0cc4e
--- /dev/null
+++ b/platform/ios/Mapbox.playground/Contents.swift
@@ -0,0 +1,133 @@
+import UIKit
+import XCPlayground
+import Mapbox
+
+let width: CGFloat = 700
+let height: CGFloat = 800
+
+//: A control panel
+let panelWidth: CGFloat = 200
+let panel = UIView(frame: CGRect(x: width - panelWidth, y: 0, width: 200, height: 100))
+panel.alpha = 0.8
+panel.backgroundColor = UIColor.whiteColor()
+let deleteSwitchLabel = UILabel(frame: CGRect(x: 0, y: 0, width: 100, height: 30))
+deleteSwitchLabel.adjustsFontSizeToFitWidth = true
+deleteSwitchLabel.text = "Delete Markers"
+let deleteMarkerSwitchView = UISwitch(frame: CGRect(x: panelWidth - panelWidth / 2.0, y:0, width: 100, height: 50))
+panel.addSubview(deleteSwitchLabel)
+panel.addSubview(deleteMarkerSwitchView)
+let hideSwitchLabel = UILabel(frame: CGRect(x: 0, y: 30, width: 100, height: 30))
+hideSwitchLabel.adjustsFontSizeToFitWidth = true
+hideSwitchLabel.text = "Hide Markers"
+let hideMarkerSwitchView = UISwitch(frame: CGRect(x: panelWidth - panelWidth / 2.0, y: 30, width: 100, height: 50))
+panel.addSubview(hideSwitchLabel)
+panel.addSubview(hideMarkerSwitchView)
+
+//: # Mapbox Maps
+
+/*:
+ Put your access token into a plain text file called `token`. Then select the “token” placeholder below, go to Editor ‣ Insert File Literal, and select the `token` file.
+ */
+var accessToken = try String(contentsOfURL: <#token#>)
+MGLAccountManager.setAccessToken(accessToken)
+
+class PlaygroundAnnotationView: MGLAnnotationView {
+
+ override func prepareForReuse() {
+ hidden = hideMarkerSwitchView.on
+ }
+
+}
+
+//: Define a map delegate
+
+class MapDelegate: NSObject, MGLMapViewDelegate {
+
+ var annotationViewByAnnotation = [MGLPointAnnotation: PlaygroundAnnotationView]()
+
+ func mapView(mapView: MGLMapView, viewForAnnotation annotation: MGLAnnotation) -> MGLAnnotationView? {
+
+ var annotationView = mapView.dequeueReusableAnnotationViewWithIdentifier("annotation") as? PlaygroundAnnotationView
+
+ if (annotationView == nil) {
+ let av = PlaygroundAnnotationView(reuseIdentifier: "annotation")
+ av.frame = CGRect(x: 0, y: 0, width: 30, height: 30)
+ let centerView = UIView(frame: CGRectInset(av.bounds, 3, 3))
+ centerView.backgroundColor = UIColor.whiteColor()
+ av.addSubview(centerView)
+ av.backgroundColor = UIColor.purpleColor()
+ annotationView = av
+ } else {
+ annotationView!.subviews.first?.backgroundColor = UIColor.greenColor()
+ }
+
+ annotationViewByAnnotation[annotation as! MGLPointAnnotation] = annotationView
+
+ return annotationView
+ }
+
+ func mapView(mapView: MGLMapView, didSelectAnnotation annotation: MGLAnnotation) {
+ let pointAnnotation = annotation as! MGLPointAnnotation
+ let annotationView: PlaygroundAnnotationView = annotationViewByAnnotation[pointAnnotation]!
+
+ for view in annotationViewByAnnotation.values {
+ view.layer.zPosition = -1
+ }
+
+ annotationView.layer.zPosition = 1
+
+ UIView.animateWithDuration(1.25, delay: 0, usingSpringWithDamping: 0.4, initialSpringVelocity: 0.6, options: .CurveEaseOut, animations: {
+ annotationView.transform = CGAffineTransformMakeScale(1.8, 1.8)
+ }) { _ in
+ annotationView.transform = CGAffineTransformMakeScale(1, 1)
+
+ if deleteMarkerSwitchView.on {
+ mapView.removeAnnotation(pointAnnotation)
+ return
+ }
+
+ if hideMarkerSwitchView.on {
+ annotationView.hidden = true
+ }
+ }
+ }
+
+ func handleTap(press: UILongPressGestureRecognizer) {
+ let mapView: MGLMapView = press.view as! MGLMapView
+
+ if (press.state == .Recognized) {
+ let coordiante: CLLocationCoordinate2D = mapView.convertPoint(press.locationInView(mapView), toCoordinateFromView: mapView)
+ let annotation = MGLPointAnnotation()
+ annotation.title = "Dropped Marker"
+ annotation.coordinate = coordiante
+ mapView.addAnnotation(annotation)
+ mapView.showAnnotations([annotation], animated: true)
+ }
+ }
+
+}
+
+//: Create a map and its delegate
+
+let lat: CLLocationDegrees = 37.174057
+let lng: CLLocationDegrees = -104.490984
+let centerCoordinate = CLLocationCoordinate2D(latitude: lat, longitude: lng)
+
+let mapView = MGLMapView(frame: CGRect(x: 0, y: 0, width: width, height: height))
+mapView.frame = CGRect(x: 0, y: 0, width: width, height: height)
+
+XCPlaygroundPage.currentPage.liveView = mapView
+
+let mapDelegate = MapDelegate()
+mapView.delegate = mapDelegate
+
+let tapGesture = UILongPressGestureRecognizer(target: mapDelegate, action: #selector(mapDelegate.handleTap))
+mapView.addGestureRecognizer(tapGesture)
+
+//: Zoom in to a location
+
+mapView.setCenterCoordinate(centerCoordinate, zoomLevel: 12, animated: false)
+
+//: Add control panel
+
+mapView.addSubview(panel)
diff --git a/platform/ios/Mapbox.playground/contents.xcplayground b/platform/ios/Mapbox.playground/contents.xcplayground
new file mode 100644
index 0000000000..35968656f5
--- /dev/null
+++ b/platform/ios/Mapbox.playground/contents.xcplayground
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<playground version='5.0' target-platform='ios' display-mode='raw'>
+ <timeline fileName='timeline.xctimeline'/>
+</playground> \ No newline at end of file
diff --git a/platform/ios/Mapbox.playground/timeline.xctimeline b/platform/ios/Mapbox.playground/timeline.xctimeline
new file mode 100644
index 0000000000..bf468afeca
--- /dev/null
+++ b/platform/ios/Mapbox.playground/timeline.xctimeline
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Timeline
+ version = "3.0">
+ <TimelineItems>
+ </TimelineItems>
+</Timeline>