Display a callout

You may want to access some information about a feature or graphic, in addition to seeing the symbol located on the map. To display text, such as, opening hours of a restaurant, use a callout. If you want to show a lot of attribute information and other media (for example, photos), use pop-ups.

A callout is anchored to a geographic location on the map so as you navigate the map, the callout will remain anchored to the same location. Text is displayed in two sections: the title and the detail. The map can only display one callout at a time so when you click elsewhere on the map, the callout is dismissed


A callout is an instance of AGSCallout. Each map has only one callout at a time that can be accessed through the callout property on AGSMapView.

Displaying a callout in response to a tap on a feature

Whenever you tap on a feature in the map, the callout's delegate is consulted to check whether or not a callout should be displayed for that feature. The delegate not only controls the display of the callout, it can also customize the information presented in the callout by modifying properties on the AGSCallout object.


The feature must belong to a layer that supports hit-testing. These layers implement the <AGSHitTestable> protocol, for example, AGSGraphicsLayer. If a layer does not support hit-testing, the map cannot detect whether a user tapped on a feature, and consquently cannot initiate the process to display a callout for it.

By default, the callout's delegate is uninitialized. This implies that there is no information to show in the callout and the map won't display a callout even when a user taps on any feature. To display a callout, you need to set one of your classes as the callout's delegate. You do this by making your class adopt the AGSCalloutDelegate protocol and implementing one ore more methods defined in the protocol. In the example below, we implement the callout:willShowForFeature:layer:mapPoint: method to display the feature's name and address in the callout -

func callout(callout: AGSCallout!, willShowForFeature feature: AGSFeature!, layer: AGSLayer!, mapPoint: AGSPoint!) -> Bool {
 //Specify the callout's contents
 mapView.callout.title = feature.attributeAsStringForKey("Name")
 mapView.callout.detail = feature.attributeAsStringForKey("Address")
 return true

Note that the method implementation returns YES at the end. This instructs the map to go ahead and display a callout. If you don't want to display the callout for some features, for example if they are missing the address attribute, you can return NO.

If you want to temporarily disable callout for all features on the map, you can set the allowCallout property on AGSMapView to NO. When you do this, the map no longer consults the callout's delegate whenever a user taps on a feature.

There will be times when you want to customize the information in the callout depending upon the type of feature for which it is being displayed. To make handling such situations easier, you can specify callout delegates on a layer-by-layer basis, instead of centrally on the callout object. To do this, you need to set one of your classes as the layer's calloutDelegate, adopt the AGSLayerCalloutDelegate protocol, and implement the callout:willShowForFeature:layer:mapPoint: method.

func callout(callout: AGSCallout!, willShowForFeature feature: AGSFeature!, layer: AGSLayer!, mapPoint: AGSPoint!) -> Bool {
	//Specify the callout's contents
	return true

The map gives precedence to the layer's callout delegate if it is available. Otherwise the map falls back to the callout's delegate as described earlier in this section. If you want to temporarily disable callout for all features in a particular layer, you can set the allowCallout property on the layer to NO.

If you're only interested in showing a feature's attribute values in the callout, the API provides an AGSCalloutTemplate class, which is a convenient implementation of the AGSLayerCalloutDelegate protocol. AGSCalloutTemplate allows you to specify title and detail text for the callout using attribute keys enclosed by ${ } characters. Attributes keys are automatically replaced by attribute values for the graphic when the callout is displayed.

let template = AGSCalloutTemplate()
template.titleTemplate = "${CITY_NAME}"; //show the value for attribute key 'CITY_NAME'
template.detailTemplate = "${POPULATION}"; //show the value for attribute key 'POPULATION'
let layer:AGSGraphicsLayer = ...
layer.calloutDelegate = template

AGSCalloutTemplate is best suited for attribute values that are strings. It does not provide the ability to localize numbers or dates.

Displaying a callout programmatically

The map has a property called allowCallout that specifies whether or not the it will attempt to display a callout when a user taps on a feature on the map. By default, this property is set to YES, in which case the map first checks if the layer that the feature belongs contains a valid calloutDelegate. This callout delegate is then given the opportunity

Although the map has the ability to automatically display a callout whenever a user taps on a feature as described above, it is sometimes useful to initiate the display of the callout through code. For example, you may want to zoom to a feature and display a callout on it in response to a tap on a table view cell.

You can display a callout programmatically using methods on AGSCallout. The showCalloutAt:screenOffset:animated: method allows you to display the callout at any arbitrary location on the map. The showCalloutAtPoint:forFeature:animated: method allows you display the callout for a particular feature.

Dismiss a callout

A callout is dismissed automatically when a user taps the map away from the callout. To dismiss a callout programatically, invoke its dismiss method.