How to support foregroundColor (deprecated) and foregroundStyle in watchOS 9/10?

In my Watch app on watchOS 9 I was using .foregroundColor(myColour) to colour the text in a widgetLabel on a corner complication like this:

let myColour: Color = functionThatReturnsAColorObjectConstructedLike Color.init(...) // green
.widgetLabel {
    Text(myText)
        .foregroundColor(myColour)
}

It worked fine; the widget label was green.

Now, in watchOS 10, I see that foregroundColor() is being deprecated in favour of foregroundStyle(), and I can use .foregroundStyle(.green), and - importantly - foregroundStyle() is only available on watchOS 10 and newer.

myColour is calculated depending on some other info, so I can't just write .green, and when I use .foregroundStyle(myColour) the widget label comes out as white every time, even if I set myColour = .green.

I think I have to use some sort of extension to pick the right combination, something like:

extension View {
	func foregroundType(colour: Colour, style: any ShapeStyle) -> some THING? {
		if #available(watchOS 10.0, *) {
			return foregroundStyle(style)
		} else {
			return foregroundColor(colour)
		}
	}
}

// Usage
let myStyle: any ShapeStyle = SOMETHING?
...
.widgetLabel {
    Text(myText)
        .foregroundType(colour: myColour, style: myStyle)

It doesn't work. I just can't figure out what should be returned, nor how to return it. Any ideas?

Right, it's pretty clear to me now that you cannot use .foregroundStyle(/* any colour */) in a corner complication.

myColour is the result of some calculations in a function, but the effect is to return a Color object of .red, .green, or .yellow.

In this example it's returning .red. Here's what happens when I use foregroundColor(myColour):

.widgetLabel {
		Text("New York")
				.foregroundColor(myColour)

This works correctly.

Now, when I use foregroundStyle(myColour):

.widgetLabel {
		Text("New York")
				.foregroundStyle(myColour)

The text is white, not red.

And now, when I use foregroundStyle(.green):

.widgetLabel {
		Text("New York")
				.foregroundStyle(.green)

The text is white, not green.

I've tried a simple example in a new project just in a standard view, not in a complication's widgetLabel:

Text("Hello, world!")
		.foregroundStyle(.green)

It works fine.

It appears that you cannot use .foregroundStyle() on a Text object within a widgetLabel.

I've also tried these in a corner complication, just removing the complexity of adding a Text object:

// 1
.widgetLabel("Hello, world!")
		.foregroundStyle(.green)

// 2
.widgetLabel("Hello, world!")
		.foregroundColor(.green)

Both of these result in the label being white.

So, either I've thoroughly misunderstood this - what should be an incredibly simple thing - or this is a bug. Apple are deprecating foregroundColor() with a broken alternative.

Happy to be proven wrong.

I think you've summarised the problem very well.

The Nil Coalescing blog "Using foregroundColor(), foregroundStyle() or tint() to set text color in SwiftUI" explains well the differences between .foregroundColor and .foregroundStyle and makes it clear that the reason .foregroundColor otherwise still works it because it still return Text rather than View.

It would be great to get some official guidance from Apple on this given we're now approaching WatchOS 11, everything is WidgetKit etc....

How to support foregroundColor (deprecated) and foregroundStyle in watchOS 9/10?
 
 
Q