SwiftUI: WidgetKit Gradient Bug

I'm trying to make a gradient for Widgets and using 2 blue colors (#0091f1 and #0054f3) but the Widget background looks green.

I've set up colors via Assets.xcassets and then using the following code:

Code Block swift
LinearGradient(gradient: Gradient(colors: [Color("color1"), Color("color2")]), startPoint: .top, endPoint: .bottom)

For the common iOS target the gradient looks right (blue) and for the Widgets extension it's green.
Could you help me to figure out why this is happening?

The link to the example with screenshots.


Replies

Does it appear blue if you don't use colours from the assets? In other words, Color.init(red:green:blue:opacity:)

Not sure it'll do anything, but how about putting the gradient in a ZStack?

Does it appear blue if you don't use colours from the assets? In other words, Color.init(red:green:blue:opacity:)

Yes, it does. Using the following code the gradient will be blue:

Code Block Swift
LinearGradient(gradient: Gradient(colors: [ Color(red: 0, green: 0.569, blue: 0.945), Color(red: 0, green: 0.329, blue: 0.953)]), startPoint: .top, endPoint: .bottom)

So, yeah. Definitely the bug is in Assets.xcassets.
In that case, I need to manually switch the code for Dark and Light themes.
This is a weird bug in Xcode 12 on the simulator. The good news is all looks normal on device, so you may need to do your testing there.

In my case, if I load the app in the simulator on my MacBook Pro 15" internal retina display the gradients are rendered fine, but if I use my external display they look like what you're showing. I've heard that's not the case for everyone though, but it's definitely an Xcode bug either way.

The issue you're experiencing might be due to the color space used by SwiftUI. SwiftUI uses the sRGB color space by default, but the color space used by iOS and Widgets might be different, which could cause the colors to appear differently.

When you define colors using hex values or other methods, the colors are interpreted according to the color space of the device where they are displayed. If the color space is different between your iOS app and the Widget extension, the same color values can appear differently.

To solve this issue for your gradient, you can try explicitly setting the color space when defining your colors. Here's an example of how to do this in SwiftUI:

Color("color1", bundle: nil).colorSpace(.sRGB)
Color("color2", bundle: nil).colorSpace(.sRGB)

This will ensure that the colors are interpreted in the sRGB color space, which should make them appear consistently between your iOS app and the Widget extension.