Examples
Customizing annotation callout text

Customizing annotation callout text

When presenting point data on your weather map using annotations, such as storm reports or earthquakes, the Xweather iOS SDK 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
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.

Grouped Styles

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 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) ?? "")"
                }
            }
        }
    }
}