iosswiftuimapkit

Setting the color of a MapPolyline to the app's accent color


I am trying to set the color of a MapPolyline to the app's accent color using .stroke().

I have tried extending ShapeStyle to have a custom definition for accent color:

extension ShapeStyle where Self == Color {
    static var accentColor: Color { Color.accentColor }
}

And modifying the MapPolyline as follows:

MapPolyline(route.route)
    .stroke(.accentColor, lineWidth: 5)

However, this leads the MapPolyline to still have the default blue color, instead of my app's accent color.

I have also tried to use the .tint ShapeStyle, and setting the accent color with .tint(Color.accentColor as an additional modifier, but this also did not work.


Solution

  • This might be an iOS bug, since this works correctly on macOS.

    A workaround is to resolve the color in the view's environment, and use the resolved color:

    @Environment(\.self) var env
    
    var body: some View {
        Map {
            MapPolyline(...)
                .stroke(Color.accentColor.resolve(in: env), lineWidth: 5)
        }
    }
    

    You can write this as a MapContent extension:

    extension MapContent {
        func strokeResolved(_ content: some ShapeStyle, style: StrokeStyle = .init()) -> some MapContent {
            Stroked(content: self, stroke: content, strokeStyle: style)
        }
    
        func strokeResolved(_ content: some ShapeStyle, lineWidth: CGFloat) -> some MapContent {
            strokeResolved(content, style: .init(lineWidth: lineWidth))
        }
    }
    
    struct Stroked<Content: MapContent, Style: ShapeStyle>: MapContent {
        @Environment(\.self) var env
        
        let content: Content
        let stroke: Style
        let strokeStyle: StrokeStyle
        
        var body: some MapContent {
            content.stroke(stroke.resolve(in: env), style: strokeStyle)
        }
    }
    
    // usage:
    .strokeResolved(.accentColor, lineWidth: 5)