GIS users may want to export a screenshot of a map to enable sharing as an image or printing.
How to use the sample
Pan and zoom to find an interesting location, then tap the button to take a screenshot. The screenshot will be displayed. Note that there may be a small delay if the map is still rendering when you tap the button.
How it works
Wait for the map view to finish rendering the map.
Call AGSMapView.exportImage(completion:) to get a UIImage object.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
// Copyright 2016 Esri.//// Licensed under the Apache License, Version 2.0 (the "License");// you may not use this file except in compliance with the License.// You may obtain a copy of the License at//// http://www.apache.org/licenses/LICENSE-2.0//// Unless required by applicable law or agreed to in writing, software// distributed under the License is distributed on an "AS IS" BASIS,// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.// See the License for the specific language governing permissions and// limitations under the License.import UIKit
import ArcGIS
classMapViewScreenshotViewController: UIViewController{
@IBOutletprivateweakvar mapView: AGSMapView!
@IBOutletprivateweakvar overlayParentView: UIView!
@IBOutletprivateweakvar overlayImageView: UIImageView!
var map: AGSMap!
var tapGestureRecognizer: UITapGestureRecognizer!
var shutterSound: SystemSoundID=0overridefuncviewDidLoad() {
super.viewDidLoad()
// add the source code button item to the right of navigation bar (self.navigationItem.rightBarButtonItem as!SourceCodeBarButtonItem).filenames = ["MapViewScreenshotViewController"]
// instantiate map with imagegry basemapself.map =AGSMap(basemapStyle: .arcGISImageryStandard)
// assign the map to the map viewself.mapView.map =self.map
// initialize and assign tap gesture to hide overlay parent viewself.tapGestureRecognizer =UITapGestureRecognizer(target: self, action: #selector(MapViewScreenshotViewController.hideOverlayParentView))
self.overlayParentView.addGestureRecognizer(self.tapGestureRecognizer)
// add border to the overlay image viewself.overlayImageView.layer.borderColor =UIColor.white.cgColor
self.overlayImageView.layer.borderWidth =2 }
// MARK: - Actions// hide the screenshot overlay view@objcfunchideOverlayParentView() {
self.overlayParentView.isHidden =true }
// show the screenshot overlay viewprivatefuncshowOverlayParentView() {
self.overlayParentView.isHidden =false }
// called when the user taps on the screenshot button@IBActionprivatefuncscreenshotAction(_sender: AnyObject) {
// hide the screenshot view if currently visibleself.hideOverlayParentView()
// the method on map view we can use to get the screenshot imageself.mapView.exportImage { [weakself] (image: UIImage?, error: Error?) iniflet error = error {
self?.presentAlert(error: error)
}
iflet image = image {
// on completion imitate flashself?.imitateFlashAndPreviewImage(image)
}
}
}
// imitate the white flash screen when the user taps on the screenshot buttonprivatefuncimitateFlashAndPreviewImage(_image: UIImage) {
let flashView =UIView(frame: self.mapView.bounds)
flashView.backgroundColor = .white
self.mapView.addSubview(flashView)
// animate the white flash view on and off to show the flash effectUIView.animate(
withDuration: 0.3,
animations: {
flashView.alpha =0 },
completion: { [weakself] (_) in// On completion play the shutter soundself?.playShutterSound()
flashView.removeFromSuperview()
// show the screenshot on screenself?.overlayImageView.image = image
self?.showOverlayParentView()
}
)
}
// to play the shutter sound once the screenshot is takenfuncplayShutterSound() {
ifself.shutterSound ==0 {
iflet filepath =Bundle.main.path(forResource: "Camera Shutter", ofType: "caf") {
let url =URL(fileURLWithPath: filepath)
AudioServicesCreateSystemSoundID(url asCFURL, &self.shutterSound)
}
}
AudioServicesPlaySystemSound(self.shutterSound)
}
deinit {
AudioServicesDisposeSystemSoundID(self.shutterSound)
}
}