0

I have written the following function which interprets a given "weather code" value and maps it to an image. Then I modify that image with the .foregroundStyle modifier.

func weatherImage(weatherCode: Int) -> Image {
    switch weatherCode {
    case 0:
        return Image(systemName: "sun.max.fill").foregroundStyle(Color.Orange)
    case 1:
        ...
    case 9: 
        return Image(systemName: "cloud.drizzle.fill").foregroundStyle(Color.white, Color.blue)
    ...
    }
}

The idea is that I could call this function from my Views in manner similar to the following example and render images with uniquely different foregroundStyle modifiers on the fly:

var body: some View {
    VStack {
        weatherImage(weatherCode: 0)
    }
}

However, doing so does not return an Image, but rather some View leading Swift to complain about the return type and it suggest adding as! Image. I have done so and then the code compiles, but at run-time this still leads to a casting error (SwiftUI.ModifiedContent versus SwiftUI.Image) and SIGABRT.

Can my solution be salvaged or is there a better way of handling this programmatically and getting these modified symbols displayed in a View?

janvdl
  • 300
  • 1
  • 10

1 Answers1

2

You just have to change the function, so it returns a View and not an Image.

Add a @ViewBuilder at the beginning, remove the returns, remember to provide a default case.


    @ViewBuilder
    func weatherImage(weatherCode: Int) -> some View {
        switch weatherCode {
            case 0:
                Image(systemName: "sun.max.fill").foregroundStyle(.orange)
            case 1:
                ...
            case 9:
                Image(systemName: "cloud.drizzle.fill").foregroundStyle(Color.white, Color.blue)
            default:
                EmptyView()
        }
    }

In the view, just call the function:

weatherImage(weatherCode: 2)
HunterLion
  • 3,496
  • 1
  • 6
  • 18
  • Thank you, that does work, but it appears to render the Image as a raster, causing it to blur when resized. Is there any way to maintain the vector graphics? – janvdl May 08 '23 at 14:06
  • Add `resizable` – jnpdx May 08 '23 at 14:11
  • I've managed to do this by modifying the function to `func weatherImage(weatherCode: Int, size: Int)` and sizing the image as a vector before returning it as raster. – janvdl May 08 '23 at 14:15