Skip to main content
Version: 6.0

Interactivity

Using Mappedin SDK for iOS with your own map requires a Pro license. Try a demo map for free or refer to the Pricing page for more information.

This guide explains how to enhance a map's interactivity by making components clickable. Interactivity can greatly improve the user experience and user engagement with a map.

tip

A complete example demonstrating interactivity can be found in the Mappedin iOS Github repo: InteractivityDemoViewController.swift

Mappedin v6 Interactivity

Interactive Spaces

A Space can be set to interactive to allow a user to click on it. When interactivity is enabled for a space, it enables a hover effect that highlights the space when the cursor is moved over the space.

The following code enables interactivity for all spaces:

// Set all spaces to be interactive so they can be clicked
mapView.mapData.getByType(.space) { [weak self] (result: Result<[Space], Error>) in
guard let self = self else { return }
if case .success(let spaces) = result {
spaces.forEach { space in
self.mapView.updateState(target: space, state: ["interactive": true]) { _ in }
}
}
}

Interactive Labels

A Label added to the map can be set to interactive to allow users to click on it and have the click event captured by an app. The code sample below adds a label to each space with a name and sets the label's interactivity to true.

// Add interactive labels to all spaces with names.
self.mapView.mapData.getByType(.space) { (spacesResult: Result<[Space], Error>) in
if case .success(let spaces) = spacesResult {
spaces.forEach { space in
guard !space.name.isEmpty else { return }
self.mapView.labels.add(
target: space,
text: space.name,
options: AddLabelOptions(interactive: true)
)
}
}
}

After enabling interactivity, click events on the label can be captured using Mapview.on('click'). The Events object passed into the on method contains an array of labels that were clicked.

The following code sample captures the click event and checks if the user clicked on a label. If they did, it logs the id of the label that was clicked and removes it from the map.

self?.mapView.on("click") { payload in
if let click = payload as? ClickPayload, let label = click.labels?.first {
print("removing label: \(label.text)")
self?.mapView.labels.remove(label: label)
}
}

Interactive Markers

A Marker can be set to interactive, allowing it to be clickable and have an app act on the click event. The interactive property of a Marker can be set to true, false or pointer-events-auto.

  • false - The Marker is not interactive.
  • true - The Marker is interactive and the click event is captured by the mapView.on('click') event handler.
  • pointer-events-auto - The Marker is interactive and mouse events are passed to the Marker's HTML content.

The code sample below adds a marker for each annotation and sets the marker's interactivity to true.

mapView.mapData.getByType(.annotation) { [weak self] (result: Result<[Annotation], Error>) in
guard let self = self else { return }
if case .success(let annotations) = result {
let opts = AddMarkerOptions(
interactive: .True,
placement: .single(.center),
rank: .tier(.high)
)

// Add markers for all annotations that have icons
annotations.forEach { annotation in
let iconUrl = annotation.icon?.url ?? ""
let markerHtml = """
<div class='mappedin-annotation-marker'>
<div style='width: 30px; height: 30px'>
<img src='\(iconUrl)' alt='\(annotation.name)' width='30' height='30' />
</div>
</div>
"""
self.mapView.markers.add(target: annotation, html: markerHtml, options: opts) { _ in }
}
}
}

After enabling interactivity, click events on the label can be captured using Mapview.on('click'). The Events object passed into the on method contains an array of markers that were clicked.

The following code sample captures the click event and checks if the user clicked on a marker. If they did, it logs the id of the marker that was clicked and removes it from the map.

// Remove markers that are clicked on
self.mapView.on(Events.click) { [weak self] payload in
guard let self = self,
let click = payload as? ClickPayload,
let clickedMarker = click.markers?.first else { return }
self.mapView.markers.remove(marker: clickedMarker) { _ in }
}

Handling Click Events

Mappedin SDK for iOS enables capturing and responding to click events through its event handling system. After enabling interactivity, click events can be captured using Mapview.on('click').

The Events click event passes ClickPayload that contains the objects the user clicked on. It allows developers to obtain information about user interactions with various elements on the map, such as:

  1. coordinate - A Coordinate object that contains the latitude and longitude of the point where the user clicked.
  2. facades - An array of Facade objects that were clicked.
  3. floors - An array of Floor objects. If the map contains multiple floors, floors under the click point are included.
  4. labels - An array of Label objects that were clicked.
  5. markers - An array of Marker objects that were clicked.
  6. models - An array of Model objects that were clicked.
  7. objects - An array of MapObject objects that were clicked.
  8. paths - An array of Path objects that were clicked.
  9. pointerEvent - A PointerEvent object that contains the pointer event data.
  10. shapes - An array of Shape objects that were clicked.
  11. spaces - An array of Space objects that were clicked.

Use Mapview.on('click') to capture click as shown below.

// Set up click listener
mapView.on("click") { [weak self] payload in
guard let self = self else { return }
if let clickPayload = payload as? ClickPayload {
self.handleClick(clickPayload)
}
}

private func handleClick(_ clickPayload: ClickPayload) {
var message = ""

// Use the map name as the title (from floors)
let title = clickPayload.floors?.first?.name ?? "Map Click"

// If a label was clicked, add its text to the message
if let labels = clickPayload.labels, !labels.isEmpty {
message.append("Label Clicked: ")
message.append(labels.first?.text ?? "")
message.append("\n")
}

// If a space was clicked, add its location name to the message
if let spaces = clickPayload.spaces, !spaces.isEmpty {
message.append("Space clicked: ")
message.append(spaces.first?.name ?? "")
message.append("\n")
}

// If a path was clicked, add it to the message
if let paths = clickPayload.paths, !paths.isEmpty {
message.append("You clicked a path.\n")
}

// Add the coordinates clicked to the message
message.append("Coordinate Clicked: \nLatitude: ")
message.append(clickPayload.coordinate.latitude.description)
message.append("\nLongitude: ")
message.append(clickPayload.coordinate.longitude.description)

print("title: \(title), message: \(message)")
}
tip

A complete example demonstrating interactivity can be found in the Mappedin iOS Github repo: InteractivityDemoViewController.swift