'How can I conform to ShapeStyle protocol in SwiftUI?

I am looking to conform to ShapeStyle, the goal is just conforming to ShapeStyle(Nothing more and nothing less).

Here is my code and the issue:

struct MyContentView: View {
    var body: some View {
        Circle()
            .fill(RedView())
    }
}

struct RedView: View {
    var body: some View {
        Color.red
    }
}

So I know I could use Color.red directly instead of a view, but as I said, the goal of this question is conformation to ShapeStyle. For those going to share apple developer link about ShapeStyle, I have to say I was there before.

Error:

Instance method 'fill(_:style:)' requires that 'RedView' conform to 'ShapeStyle'



Solution 1:[1]

Disclaimer: below is only for demo, because all used API are private (by convention, not by design), so reaction of Apple if you submit app with such code to AppStore is unpredictable.

Note: as used interfaces are private they can be changed with any new version.

Main part:

  public func _apply(to shape: inout SwiftUI._ShapeStyle_Shape) {
    Color.red._apply(to: &shape)  // << here !!
  }

Which gives on Xcode 13.3 / iOS 15.4

demo

Complete findings and code is here

Solution 2:[2]

If you want any kind of View to conform to ShapeStyle, then @Asperi provided here the answer.

If you want a Color to conform to ShapeStyle like in your example, it already adopts that protocol, so you just need a little tweak to make it work, like this:

struct RedView {
    var render: some ShapeStyle {
        Color.red
    }
}

struct MyContentView: View {
    var body: some View {
        Circle()
            .fill(RedView().render)
    }
}

Solution 3:[3]

From the documentation for ShapeStyle:

You don’t use the ShapeStyle protocol directly. Instead, use one of the concrete styles that SwiftUI defines. To indicate a specific color or pattern, you can use Color or the style returned by image(_:sourceRect:scale:), or one of the gradient types, like the one returned by radialGradient(_:center:startRadius:endRadius:). To set a color that’s appropriate for a given context on a given platform, use one of the semantic styles, like background or primary.

I believe what you're trying to do can be achieved with:

struct MyContentView: View {
    var body: some View {
        Circle()
            .fill(.red)
    }
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2
Solution 3 Pylyp Dukhov