- Developers
- Sygic Maps SDK
- iOS
- Maps
Maps
- Move to section
The key concepts covered in this section include adding a map to your iOS application, changing the location displayed on the map, and modifying its properties. The primary component of the maps API is the SYMapView, which is integrated with the Cocoa Touch framework as a UIView subclass. SYMapView represents the view that displays a map and various properties. The SYMapView is derived from UIView and part of iOS Cocoa Touch framework.
The first step to integrate a map into an application is to insert a SYMapView to your view controller.
Remember to wait for the SDK initialization to be finished before displaying the map
class ViewController: UIViewController, SYMapViewDelegate {
func viewDidLoad () {
}
var mapView: SYMapView?
func initMap() {
self.mapView = SYMapView(frame: self.view.bounds)
if let _mapView = self.mapView {
_mapView.delegate = self
_mapView.geoCenter = SYGeoCoordinate(latitude: 48.145810, longitude: 17.126420)!
self.view.addSubview(_mapView)
}
}
}
Now run your application, you should now see a globe displayed

The SYMapView class handles all user interactions in the form of touch gestures. More details about the supported gesture types can be found in the Gestures section.
Map Handling
Once the SYMapView is initialized, it can be manipulated and interacted in a variety of ways. Some key attributes of the SYMapView are its orientation, tilt, geographical center (geoCenter), and zoom level (zoom). These properties may be used to customize the SYMapView display.
Zoom Level
The size of the geographical area displayed by the map can be controlled by changing the zoom level.
The zoom level determines how "close" the map view is to the surface of the Earth. Higher zoom levels give a closer view. Zoom 1 is the view on the earth, zoom 10 is approximately view on city, 15 on street, etc.
Try adding _mapView.zoom = 12
to your map initialization.
class ViewController: UIViewController, SYMapViewDelegate {
func viewDidLoad () {
}
var mapView: SYMapView?
// should be called after SDK initialization finished
func initMap() {
self.mapView = SYMapView(frame: self.view.bounds)
if let _mapView = self.mapView {
_mapView.delegate = self
_mapView.camera.geoCenter = SYGeoCoordinate(latitude: 48.145810, longitude: 17.126420)
_mapView.camera.zoom = 17
self.view.addSubview(_mapView)
}
}
}
You should now see location of the Sygic HQ with street level zoom.
Now try setting higher or lower zoom levels.
Rotation
The rotation determines which cardinal direction corresponds with which screen direction of the SyMapView. The valid range is from 0 to 360 degrees. The default value of 0 orients the map so that true north is toward the top of the view. The following code shows how to set the orientation to south-up:
_mapView.camera.rotation = 180
Tilt
The tilt value represents the angle at which the map is viewed. By default, the map tilt value is 0. This provides a top-down two-dimensional view of the map. You can set a tilt value using the tilt property in SYMapView, but since the valid range of tilt values is dependent on the current zoom level, this tilt property is converted before it is used on screen.
// set tilt for 2D to 0, for 3D to 60
let tiltFor2D: SYAngle = 0
let tiltFor3D: SYAngle = 60
// ...
_mapView.camera.tilt = self.tiltFor2D
// ...

FPS Limitter
In order to save battery, setFpsLimitMode method of SYMapView class enables you to set the maximum FPS performance of your App. There are 2 modes available:
- SYFpsLimitModePerformance - Always try to run at maximum fps.
- SYFpsLimitModeBalanced - Try to achieve smooth camera movement with minimum performance requirements.
_mapView.setFpsLimitMode(.balanced, withFpsLimit: 15.0)
Handling map rendering
Another way to save battery is to turn off rendering of map. This can be useful when the map is fully obscured by other view (e.g. another ViewController).
Remember to turn it back on when the map is visible again.
_mapView.renderEnabled = false
Animations
The SYMapView supports the following animation settings to be used while changing properties, defined by the SYAnimation:
rotateView
- angle - Camera rotation offset in degrees.
- duration - Animation duration.
- curve - Animation curve.
- completion - Animation completition block.
_mapView.camera.rotateView(90.0, withDuration: 1.0, curve: .decelerate, completion: nil)
dragView
- drag - Camera move offset in screen points.
- duration - Animation duration.
- curve - Animation curve.
- completion - Animation completition block.
_mapView.camera.dragView(CGPoint(x: 50.0, y: 100.0), withDuration: 1.0, curve: .decelerate, completion: nil)
dragViewFrom
- from - Screen from point.
- to - Screen to point.
- duration - Animation duration.
- curve - Animation curve.
- completion - Animation completition block.
_mapView.camera.dragView(from: CGPoint(x: 0.0, y: 0.0), to: CGPoint(x: 50.0, y: 50.0), withDuration: 1.0, curve: .linear, completion: nil)
zoomView
- zoom - Zoom scale.
- center - Screen point to zoom at. Usually represents center of pinch gesture toches. Ignored if SYMapView.cameraMovementMode is not SYCameraMovementFree.
- duration - Animation duration.
- curve - Animation curve.
- completion - Animation completition block.
_mapView.camera.zoomView(2.0, at: CGPoint(x: 250.0, y: 250.0), withDuration: 2.0, curve: .accelerate, completion: nil)
animate
- animations - Animation block containing properties changes. Animable properties are geoCenter, transformCenter, rotation, tilt, and zoom.
- duration - Animation duration.
- curve - Animation curve.
- completion - Animation completition block.
_mapView.camera.animate({
_mapView.camera.tilt = 20.0
_mapView.camera.zoom = 11
_mapView.camera.rotation = 180.0
_mapView.camera.geoCenter = SYGeoCoordinate(latitude: 48.147, longitude: 17.101878)
}, withDuration: 1.0, curve: .decelerate, completion: nil)
Here are the available SYMapAnimationCurve types:
- SYMapAnimationCurveLinear ( swift .linear) - A linear animation curve causes an animation to occur evenly over its duration.
- SYMapAnimationCurveAccelerate ( swift .accelerate) - This curve causes the animation to accelerate.
- SYMapAnimationCurveDecelerate ( swift .decelerate) - This curve causes the animation to slow down.
- SYMapAnimationCurveAccelerateDecelerate ( swift .accelerateDecelerate) - This curve causes the animation to accelerate first and decelerate at the end.
- SYMapAnimationCurveBounce ( swift .bounce) - This curve will toggle the animation to bounce.
Handling Map Inputs
Sygic iOS SDK enables to handle all map inputs the application user makes. This is important to setting map markers or to choose the waypoints directly from the map. The following code shows, how to get GPS Coordinates or point in MapView from taping on a map.
class ViewController: UIViewController {
func viewDidLoad() {
}
var mapView: SYMapView?
func initMap() {
self.mapView = SYMapView(frame: self.view.bounds)
if let _mapView = self.mapView {
_mapView.delegate = self
_mapView.camera.geoCenter = SYGeoCoordinate(latitude: 48.145810, longitude: 17.126420)
_mapView.camera.zoom = 17
// Setup tapGesture recognizer
let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(self.tapped(_:)))
_mapView.addGestureRecognizer(tapGestureRecognizer)
self.view.addSubview(_mapView)
}
}
@objc func tapped (_ recognizer: UITapGestureRecognizer) {
// Get point on screen
let point = recognizer.location(in: self.mapView)
// Convert point to NSValue
let value = NSValue(cgPoint: point)
// Get coordinates for point from screen
if let coordinates = self.mapView?.geoCoordinates(fromScreenPoints: [value]) {
// now handle the coordinates, as you wish
print(coordinates)
}
}
}
Map Skins
Specific map skins are available to offer your application users a choice among different kinds of map appearance. Currently we support day and night themes alongside with car and pedestrian navigation types. You can combine your skin as theme + navigation type.
// To get available skins:
let activeSkins = _mapView.availableSkins() // returns ["browse", "car", "car_custom", "car_no_signal", "day", "default", "low_performance", "navigation", "night", "pedestrian", "pedestrian_no_signal", "realview", "scout"]
// For example, to set a night theme for car navigation type:
_mapView.activeSkins = ["night", "car"]

Gestures
The SYMapView class responds to a number of predefined touch gestures. The default behavior of the map for each gesture type may be used as-is, supplemented, or replaced entirely. The following table is a summary of the available gestures and their default behavior.
Gesture | Description | Following gestures | ||
Rotate | Rotate: Two-finger press, simultaneously orbit both fingers around the center point, lift | Pinch, Spread, Move | ||
Zoom out | Pinch: Two-finger press, move inwards, lift | Spread, Rotate, Move | ||
Zoom in | Spread: Two-finger press, move outwards, lift | |||
Move | Swipe: One-finger press, move, lift/don't lift | |||
Tilt | Tilt: Two fingers press, move up (increase the tilt angle) or move down (decrease the tilt angle) | |||
Short touch | Short touch: One-finger press, lift |
You can disable interaction with SYMapView by setting mapInteractionEnabled property to false
_mapView.mapInteractionEnabled = false
Objects and Interaction
The Sygic Mobile SDK allows customization and extensibility by adding variety of objects to a map view. The types of available objects include map markers, routes, polylines, circles. To see full list of objects available, check the SYMapObjectType API reference. Some objects are described in more detail below.
The SYMapObject class provides a generic base class from which most of the specialized map object types inherit. The following is a list of the important properties and methods in SYMapObject.
- type - contains the type of the map object, such as marker, polyline, circle our route. For the full list, see the SYMapObject API reference.
- zIndex - determines the objects stacking order, which controls how the object is displayed on the map relative to other objects that may overlap it. Objects with the highest value are placed at the top of the view.
- visible - determines whether or not the object is drawn on the map view.
In order to display the map object on the map, call addMapObject: on a SYMapView
Assuming you know how to add image asset to your application (if not please follow iOS developer guide ) following example shows how to display marker on a map.
let marker: SYMapMarker = SYMapMarker(
coordinate: SYGeoCoordinate(latitude: 48.145810, longitude: 17.126420),
image: UIImage.init(named: "your_image_resource")!
)
_mapView.add(marker)
SYMapCircle
Enables you to draw a circle on the map at a fixed geographical location. You can customize you circle's color, radius, lineColor.
See the SYMapCircle API reference for more information.
let circle: SYMapCircle = SYMapCircle(geoCenter: SYGeoCoordinate(latitude: 48.145810, longitude: 17.126420), radius: 40)
circle.fillColor = UIColor(hue: 236, saturation: 27, brightness: 46, alpha: 0.5)
_mapView.add(circle)

SYMapPolyline
Enables you to draw one or more connected line segments on the map. The segment vertices are specified by a series of SYGeoCoordinates. The visual appearance of the polyline can be customized.
See the SYMapPolyline API reference for more information.
let polyline = SYMapPolyline(coordinates: [
SYGeoCoordinate(latitude: 48.1418807, longitude: 17.099226),
SYGeoCoordinate(latitude: 48.1551798, longitude: 17.1251751),
SYGeoCoordinate(latitude: 48.1458952, longitude: 17.1246556)
])
_mapView.add(polyline)

SYMapMarker
With Sygic Mobile SDK you can display a icon at a fixed geographical position on the map.
let marker: SYMapMarker = SYMapMarker(
coordinate: SYGeoCoordinate(latitude: 48.145810, longitude: 17.126420),
image: UIImage.init(named: "your_image_resource")!
)
_mapView.add(marker)

Each of these objects could be selected by either tapping on the map, which returns the objects from the mapView:didSelectObjects: callback method in SYMapViewDelegate, or by calling the objectsAtPoint: method in SYMapView.
Offline Maps
Sygic iOS SDK is able to pre-load map data, allowing the use of maps, search, routing, and other features without an active data connection. Interfaces involved in providing offline maps functionality include SYMapLoader, SYMapLoaderDelegate and SYCountryDetails.
SYMapLoader identifies a country by it's ISO code (usually, a two-letter string).
In SYMapLoader calls, always use ISO codes received directly from SYMapLoader (it's not guaranteed that SYMapLoader always operates with ISO 3166 alpha-2 standard).
SYMapLoader API provides such operations with map data stored on the device:
- getAvailableCountries - returns ISO codes for:
- SYMapLoaderMapFilterAll - all countries (already downloaded + available for download)
- SYMapLoaderMapFilterInstalled - only downloaded countries
- getCountryDetails - get details by a country ISO code
- getRegionDetails - get details by a region ISO code (some big countries are be split into regions)
- installMap - download map data for a country ISO code or a region ISO code
- uninstallMap - remove map data, associated with the specified ISO code, from the device
- getMapStatus - not installed, installed, loaded, etc.
- loadMap - after map is downloaded, it must be loaded to make it available for browsing, searching, routing, etc.
- unloadMap
- checkForUpdates - check if the new map data is available for the specified ISO code
- updateMap - download new map data for the specified ISO code
- detectCurrentCountry - 2 modes:
- detect current county ISO code automatically by the current IP-address
- get county ISO code from the region ISO code
- resumePendingInstallations - resume downloads which were in progress when the app was terminated, if any
Example: list all available countries
class Country {
var iso: String
var details: SYCountryDetails
var isInstalled: Bool
init(_ iso: String, _ details: SYCountryDetails, isInstalled: Bool) {
self.iso = iso
self.details = details
self.isInstalled = isInstalled
}
}
class Example: NSObject, SYMapLoaderDelegate {
var countries = [SYCountryDetails]()
func demoGetCountries() {
let mapLoader = SYMapLoader()
// get all countries
mapLoader.getAvailableCountries(.all) { (isoCodes: [String], result: SYMapLoaderResult) in
guard result == .success else {
print("Error getAvailableCountries: \(result.rawValue)")
return
}
var remainingCount = isoCodes.count
isoCodes.forEach { (iso: String) in
// get country details
mapLoader.getCountryDetails(iso, installedOnly: false) { (result: SYMapLoaderResult, details: SYCountryDetails?) in
if let details = details {
self.countries.append(details)
}
else {
print("Error getCountryDetails '\(iso)' result=\(result.rawValue)")
}
remainingCount -= 1
if remainingCount == 0 {
// all countries are processed, data is ready
self.printCountries()
}
}
}
}
}
func printCountries() {
countries.forEach { (country: SYCountryDetails) in
let continent = country.continentName
let name = country.name
let size = country.totalSize
print("\(continent), '\(country.iso)' \(name) \(size) bytes")
}
}
}
Example: install a map
func installCountry(_ country: SYCountryDetails) {
let mapLoader = SYMapLoader()
mapLoader.delegate = self // listen to downloading progress
mapLoader.installMap(country.iso) { (iso: String, result: SYMapLoaderResult) in
guard result == .success else {
print("Error installMap \(iso): \(result.rawValue)")
return
}
// load the map to enable rendering, searching, routing
mapLoader.loadMap(iso) { (result: SYMapLoaderResult) in
print("loadMap '\(iso)' result=\(result.rawValue)")
}
}
}
The resumePendingInstallations method checks if some map downloads were interrupted by application exit, and resumes them. If there are no pending installations, the method will finish with completion resumedInstalls = 0, resumedUpdates = 0.
func demoResumePendingInstallations() {
let mapLoader = SYMapLoader()
mapLoader.delegate = self
mapLoader.resumePendingInstallations { (resumedInstalls: [SYMapLoaderResumedTaskDetails], resumedUpdates: [SYMapLoaderResumedTaskDetails], result: SYMapLoaderResult) in
print("resumePendingInstallations -> \(result.rawValue), resumedInstalls: \(resumedInstalls.count), resumedUpdates: \(resumedUpdates.count)")
}
}
func mapLoader(_ maploader: SYMapLoader, didFinishResumedInstallWith result: SYMapLoaderResult, forMap map: String) {
print("didFinishResumedInstallWith result=\(result.rawValue) map=\(map)")
}
Optional information about SYMapLoader operations can be received by implementing such methods of SYMapLoaderDelegate:
- (void)mapLoader:(nonnull SYMapLoader*)maploader didFinishResumedInstallWithResult:(SYMapLoaderResult)result forMap:(nonnull SYCountryIso*)map;
- (void)mapLoader:(nonnull SYMapLoader*)maploader didUpdateMapInstallProgress:(nonnull SYMapInstallProgress*)progress forMap:(nonnull SYCountryIso*)map;
Note: these methods will be called on delegates of all SYMapLoader instances, even if an operation was requested only on one SYMapLoader.
SYMapLoader instances can be created only when SYContext is already initialized.
When Sygic SDK is initialized, all installed maps are loaded automatically, but when the new map is installed, SYMapLoader.loadMap must be called before the map data can be used (for rendering, search, etc.).
All asynchronous operations return SYTask object, it can be used to cancel the operation. If the operation is cancelled, it's completion will be called with result SYMapLoaderResultCancelled. However, it's possible that the operation has already finished internally at the moment of the cancellation request, in this case the completion block will be called with a regular non-cancelled result.
- Previous article: Getting Started
- Next article: Routing