【SwiftUI】ShapeStyleのopacityの濃さがOSバージョンによって変わる

# はじめに
SwiftUIはOSバージョンによって動きが変わることがよくあります笑

最近はなかなかなく、安定してきたかなと思っていたら遭遇しました。

ちなみに、原因は全くわかりません。
記事を見て何かわかった方はコメントください。

# 何が起こるのか
以下は同じコードで実行したものです。
明らかに透明度が異なります。

![スクリーンショット 2023-12-13 20.20.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/33eb8ec5-d9b1-8818-4a69-9f8d271f65be.png)

左から`iOS15.5`、`iOS16.0`、`iOS17.0`です。

# 発生条件
- `foregroundStyle`で`AnyShapeStyle`を使用する
- `AnyShapeStyle`に対して`opacity`で透明度を変更する

# コード
```swift
import SwiftUI

struct ContentView: View {
    private let textStyle = AnyShapeStyle(Color.red)

    var body: some View {
        VStack {
            Text("Hello World!!")
                .font(.title)
                .foregroundStyle(textStyle.opacity(1.0))
            
            Text("Hello World!!")
                .font(.title)
                .foregroundStyle(textStyle.opacity(0.9))
            
            Text("Hello World!!")
                .font(.title)
                .foregroundStyle(textStyle.opacity(0.8))
            
            Text("Hello World!!")
                .font(.title)
                .foregroundStyle(textStyle.opacity(0.7))
            
            Text("Hello World!!")
                .font(.title)
                .foregroundStyle(textStyle.opacity(0.6))
            
            Text("Hello World!!")
                .font(.title)
                .foregroundStyle(textStyle.opacity(0.5))
            
            Text("Hello World!!")
                .font(.title)
                .foregroundStyle(textStyle.opacity(0.4))
            
            Text("Hello World!!")
                .font(.title)
                .foregroundStyle(textStyle.opacity(0.3))
            
            Text("Hello World!!")
                .font(.title)
                .foregroundStyle(textStyle.opacity(0.2))
            
            Text("Hello World!!")
                .font(.title)
                .foregroundStyle(textStyle.opacity(0.1))
            
            Text("Hello World!!")
                .font(.title)
                .foregroundStyle(textStyle.opacity(0.0))
        }
    }
}
```

# 対策1
`AnyShapeStyle`の使用をやめることで解決します。
しかし、どうしても`AnyShapeStyle`を使わなくてはいけない場面では対策になりません。
```swift
import SwiftUI

struct ContentView: View {
    private let textStyle = Color.red

    var body: some View {
        VStack {
            Text("Hello World!!")
                .font(.title)
                .foregroundStyle(textStyle.opacity(1.0))
            
            Text("Hello World!!")
                .font(.title)
                .foregroundStyle(textStyle.opacity(0.9))
            
            Text("Hello World!!")
                .font(.title)
                .foregroundStyle(textStyle.opacity(0.8))
            
            Text("Hello World!!")
                .font(.title)
                .foregroundStyle(textStyle.opacity(0.7))
            
            Text("Hello World!!")
                .font(.title)
                .foregroundStyle(textStyle.opacity(0.6))
            
            Text("Hello World!!")
                .font(.title)
                .foregroundStyle(textStyle.opacity(0.5))
            
            Text("Hello World!!")
                .font(.title)
                .foregroundStyle(textStyle.opacity(0.4))
            
            Text("Hello World!!")
                .font(.title)
                .foregroundStyle(textStyle.opacity(0.3))
            
            Text("Hello World!!")
                .font(.title)
                .foregroundStyle(textStyle.opacity(0.2))
            
            Text("Hello World!!")
                .font(.title)
                .foregroundStyle(textStyle.opacity(0.1))
            
            Text("Hello World!!")
                .font(.title)
                .foregroundStyle(textStyle.opacity(0.0))
        }
    }
}
```

# 対策2
`Text`に対して`opacity`を付与する。
Viewの透明度を変更することで同じ結果が得られると思います。
```swift
import SwiftUI

struct ContentView: View {
    private let textStyle = AnyShapeStyle(Color.red)

    var body: some View {
        VStack {
            Text("Hello World!!")
                .font(.title)
                .foregroundStyle(textStyle)
                .opacity(1.0)
            
            Text("Hello World!!")
                .font(.title)
                .foregroundStyle(textStyle)
                .opacity(0.9)
            
            Text("Hello World!!")
                .font(.title)
                .foregroundStyle(textStyle)
                .opacity(0.8)
            
            Text("Hello World!!")
                .font(.title)
                .foregroundStyle(textStyle)
                .opacity(0.7)
            
            Text("Hello World!!")
                .font(.title)
                .foregroundStyle(textStyle)
                .opacity(0.6)
            
            Text("Hello World!!")
                .font(.title)
                .foregroundStyle(textStyle)
                .opacity(0.5)
            
            Text("Hello World!!")
                .font(.title)
                .foregroundStyle(textStyle)
                .opacity(0.4)
            
            Text("Hello World!!")
                .font(.title)
                .foregroundStyle(textStyle)
                .opacity(0.3)
            
            Text("Hello World!!")
                .font(.title)
                .foregroundStyle(textStyle)
                .opacity(0.2)
            
            Text("Hello World!!")
                .font(.title)
                .foregroundStyle(textStyle)
                .opacity(0.1)
            
            Text("Hello World!!")
                .font(.title)
                .foregroundStyle(textStyle)
                .opacity(0.0)
        }
    }
}
```

# おわり
中間バージョンだけ挙動が違うのは珍しい気がする