> For the complete documentation index, see [llms.txt](https://docs.mapbox.com/ios/maps/llms.txt)

# SwiftUI - Weather annotations

![Show view annotations with contents changed on selection.](https://docs.mapbox.com/ios/assets/ideal-img/maps-examples-swiftui-weather.35cc6f8.480.png)

This example shows how to display weather data as [annotations](https://docs.mapbox.com/ios/maps/guides/markers-and-annotations/) on a map using the **Mapbox Maps SDK for iOS**. The weather data includes point features with properties such as temperature, and icon name for each. The annotations are interactive, and upon selection, the view will adjust the viewport to focus on the selected annotation and animate the annotation to be larger and include additional information.

The example includes a SwiftUI view named `WeatherIconView`, which is a component to render individual weather icons. Users can tap on an icon to select it, updating the selection state and triggering an animation. The weather icons are displayed within circles, with varying sizes based on the selection status. This setup allows for an engaging visualization of weather data on the map.

> **Note: iOS Examples App Available**
> 
> This example code is part of the **Maps SDK for iOS Examples App**, a working iOS project [available on Github](https://github.com/mapbox/mapbox-maps-ios/tree/11.31.0/Sources/Examples). iOS developers are encouraged to run the examples app locally to interact with this example in an emulator and explore other features of the Maps SDK.
> 
> See our [Run the Maps SDK for iOS Examples App](https://docs.mapbox.com/help/tutorials/maps-sdk-ios-examples-app/) tutorial for step-by-step instructions.

**Swift**

Title: `WeatherAnnotationExample.swift`

[View on GitHub](https://github.com/mapbox/mapbox-maps-ios/blob/main/Sources/Examples/SwiftUI%20Examples/WeatherAnnotationExample.swift)

```swift
import SwiftUI
import MapboxMaps

private struct WeatherData: Identifiable, Equatable {
    let id = UUID().uuidString
    let coordinate: CLLocationCoordinate2D
    let temperature: Measurement<UnitTemperature>
    let iconName: String
}

struct WeatherAnnotationExample: View {
    @State private var viewport: Viewport = .camera(center: .berlin, zoom: 1.5)

    @State private var selectedData: WeatherData?
    private var weatherData: [WeatherData] = [
        WeatherData(coordinate: .helsinki, temperature: Measurement(value: 25, unit: .celsius), iconName: "sun.min.fill"),
        WeatherData(coordinate: .london, temperature: Measurement(value: 20, unit: .celsius), iconName: "cloud.drizzle.fill"),
        WeatherData(coordinate: .berlin, temperature: Measurement(value: 30, unit: .celsius), iconName: "cloud.bolt.rain.fill")
    ]

    var body: some View {
        Map(viewport: $viewport) {
            ForEvery(weatherData) { data in
                MapViewAnnotation(coordinate: data.coordinate) {
                    WeatherIconView(data: data, selectedData: $selectedData)
                }
            }
        }
        .onChange(of: selectedData?.coordinate) { center in
            guard let center else { return }

            withViewportAnimation(.default(maxDuration: 0.5)) {
                viewport = .camera(center: center, zoom: 2.5)
            }
        }
        .ignoresSafeArea()
    }
}

private struct WeatherIconView: View {
    var data: WeatherData
    @Binding var selectedData: WeatherData?
    @State private var isSelected = false

    private let formatter: MeasurementFormatter = {
        let formatter = MeasurementFormatter()
        formatter.unitOptions = .providedUnit
        return formatter
    }()

    var body: some View {
        ZStack {
            Circle()
                .stroke(.white, lineWidth: 3)
                .overlay(Circle().fill(.blue))
                .frame(width: isSelected ? 50 : 35, height: isSelected ? 50 : 35)
            VStack {
                if isSelected {
                    Text(formatter.string(from: data.temperature))
                        .font(.caption2)
                }
                Image(systemName: data.iconName)
            }
        }
        .foregroundColor(.white)
        .onTapGesture {
            selectedData = data
        }
        .onChange(of: selectedData) { selectedData in
            withAnimation(.interactiveSpring()) {
                isSelected = selectedData == data
            }
        }
    }
}
struct WeatherAnnotationExample_Preview: PreviewProvider {

    static var previews: some View {
        WeatherAnnotationExample()
    }
}
```