When presenting point data on your weather map using annotations, such as storm reports or earthquakes, the AerisWeather SDK for iOS will automatically format the text that is presented in an annotation’s callout view. In most cases this information will be sufficient. However, you may want to customize the text that is displayed for the title and/or subtitle of the annotation callout.
By default, each map layer type associated with point content sources has a style associated with it, which is either and instance of AWFAnnotationStyle
or AWFGroupedStyle
. Annotation callout text can be customized using the callout formatter block associated with the layer’s style.
Therefore, you will need to get the style associated with a particular layer type from your weather map and use the setCalloutFormatter
method to override the default annotation callout text:
// get the current style instance associated with the earthquake layer
id<AWFStyleProvider> earthquakeStyle = [self.weatherMap.style styleForLayerType:AWFMapLayerEarthquakes];
// make sure style is an instance of AWFAnnotationStyle
if ([earthquakeStyle isKindOfClass:[AWFAnnotationStyle class]]) {
// override the default callout formatter
[(AWFAnnotationStyle *)earthquakeStyle setCalloutFormatter:^(NSObject<AWFAnnotation> * _Nonnull annotation) {
// make sure the model object associated with the annotation is an AWFEarthquake instance
if ([annotation.modelObject isKindOfClass:[AWFEarthquake class]]) {
AWFEarthquake *report = (AWFEarthquake *)annotation.modelObject;
// set the callout title text
annotation.title = [NSString stringWithFormat:@"%.2f (%@)", report.magnitude, (report.type ? report.type : @"")];
// set the callout subtitle text if `timestamp` is defined on the model
if (report.timestamp) {
annotation.subtitle = [report.timestamp awf_formattedDateWithFormat:@"M/d/y h:mm a" timeZone:report.place.timeZone];
}
}
}];
}
// get the current style instance associated with the earthquake layer
if let earthquakeStyle = weatherMap.style.style(forLayerType: .earthquakes) as? AWFAnnotationStyle {
// override the default callout formatter
earthquakeStyle.setCalloutFormatter { (annotation) in
// make sure model object associated with the annotation is an AWFEarthquake instance
guard let report = annotation.modelObject as? AWFEarthquake else { return }
// set the callout title text
annotation.title = "\(report.magnitude) \(report.type ?? "")"
// set the callout subtitle text if `timestamp` is defined on the model
if let timestamp = report.timestamp, let timeZone = report.place?.timeZone {
annotation.subtitle = "\((timestamp as NSDate).awf_formattedDate(withFormat: "M/d/y h:mm a", timeZone: timeZone) ?? "")"
}
}
}
Note that if you need to access data from the model object represented by an annotation, you can do so by accessing the modelObject
property on the annotation passed to your callout formatter block. You will need to check the model object’s type and cast it to the appropriate type for the map layer before trying to access its properties.
If the style associated with a particular map layer is an AWFGroupedStyle
instead of AWFAnnotationStyle
, you will need to step through each style within the group and set the callout formatter. To do so, simply iterate through the values of a group’s styles
property, which will be instances of AWFAnnotationStyle
as mentioned above for single styles.
So we can use the same code as above, but we just move it into the iterator block for the group’s styles:
if ([earthquakeStyle isKindOfClass:[AWFGroupedStyle class]]) {
// iterate through the style group's series of styles and set the callout formatter
[((AWFGroupedStyle *)earthquakeStyle).styles enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull key, AWFMapItemStyle * _Nonnull style, BOOL * _Nonnull stop) {
// make sure style is an instance of AWFAnnotationStyle
if ([style isKindOfClass:[AWFAnnotationStyle class]]) {
// override the default callout formatter
[(AWFAnnotationStyle *)style setCalloutFormatter:^(NSObject<AWFAnnotation> * _Nonnull annotation) {
// make sure the model object associated with the annotation is an AWFEarthquake instance
if ([annotation.modelObject isKindOfClass:[AWFEarthquake class]]) {
AWFEarthquake *report = (AWFEarthquake *)annotation.modelObject;
// set the callout title text
annotation.title = [NSString stringWithFormat:@"%.2f (%@)", report.magnitude, (report.type ? report.type : @"")];
// set the callout subtitle text if `timestamp` is defined on the model
if (report.timestamp) {
annotation.subtitle = [report.timestamp awf_formattedDateWithFormat:@"M/d/y h:mm a" timeZone:report.place.timeZone];
}
}
}];
}
}];
}
if let group = weatherMap.style.style(forLayerType: .earthquakes) as? AWFGroupedStyle {
// iterate through the style group's series of styles and set the callout formatter
group.styles.forEach { (key, style) in
// make sure style is an instance of AWFAnnotationStyle
if let earthquakeStyle = style as? AWFAnnotationStyle {
// override the default callout formatter
earthquakeStyle.setCalloutFormatter { (annotation) in
// make sure model object associated with the annotation is an AWFEarthquake instance
guard let report = annotation.modelObject as? AWFEarthquake else { return }
// set the callout title text
annotation.title = "\(report.magnitude) \(report.type ?? "")"
// set the callout subtitle text if `timestamp` is defined on the model
if let timestamp = report.timestamp, let timeZone = report.place?.timeZone {
annotation.subtitle = "\((timestamp as NSDate).awf_formattedDate(withFormat: "M/d/y h:mm a", timeZone: timeZone) ?? "")"
}
}
}
}
}
Last modified: July 30, 2020