I just got my new Apple Watch series 9 - woo! But I loaded a couple of my test apps onto it - and the complications are not rendering. They work fine on my "old" series 6 (both are on WatchOS 10).
I tried resizing them. They run and render fine in the simulator. But this is how it looks on my actual watch (the upper 2 complications are mine).
You need to implement .containerBackground()
- which is new in watchOS 10. It doesn't work on watchOS 9, so simply adding it will bring compile errors.
To get it to work I have a 'backport' extension, as per Dave DeLong's blog here: https://davedelong.com/blog/2021/10/09/simplifying-backwards-compatibility-in-swift/
Here's how to implement it:
// MARK: - Backports
public struct Backport<Content> {
public let content: Content
public init(_ content: Content) {
self.content = content
}
}
extension View {
var backport: Backport<Self> { Backport(self) }
}
extension Backport where Content: View {
@ViewBuilder func containerBackground(_ backgroundView: some View) -> some View {
if #available(watchOS 10.0, iOSApplicationExtension 17.0, iOS 17.0, macOSApplicationExtension 14.0, *) {
content.containerBackground(for: .widget) {
backgroundView
}
} else {
backgroundView
}
}
@ViewBuilder func widgetCurvesContent() -> some View {
if #available(watchOS 10.0, iOSApplicationExtension 17.0, iOS 17.0, macOSApplicationExtension 14.0, *) {
content.widgetCurvesContent()
} else {
content
}
}
}
I've also added a widgetCurvesContent
function so you can see how to use it for other, simpler cases. As the blog says, naming these functions the same as the one they're implementing means it's easy to move forward when you no longer have to support a backport. You would just delete the function from the extension, let Xcode's errors tell you where you were using it, and remove the .backport
bit, i.e. .backport.containerBackground(...)
-> .containerBackground(...)
.
Now, to use it:
.backport.containerBackground(
Circle()
.fill(.red.gradient)
.opacity(0.75)
)
Here, you're passing in a Circle
object as the backgroundView
to the backport.containerBackground
function. If you're using watchOS 10 it will apply the containerBackground
function with your backgroundView
. If you're on watchOS 9 it falls back to just applying the backgroundView
.
For the simpler case of applying a modifier to something like the text in a corner widget to make it curved, you can use .widgetCurvesContent()
. Again, this is only available in watchOS 10+, so you can use the backport function .backport.widgetCurvesContent()
.
Hope this helps.