Sponsor Link
環境&対象
- macOS14.4
- Xcode 15.2
- iOS 17.2
- Swift 5.9
.foregruondColor v.s. foregroundStyle
SwiftUI 登場当初は、Text の描画色を変更するのには、.foregroundColor という View Modifier を使用していました。
表示が見やすくなるよう .font(.largeTitle) 指定を入れています。
Text("Hello, world!")
.font(.largeTitle)
.foregroundColor(.red)
参考
foregroundColorApple Developer Documentation
macOS14/ iOS17 以降は、.foregroundStyle という View Modifier を使用するように推奨されています。
Text("Hello, world!")
.font(.largeTitle)
.foregroundStyle(.red)
参考
foregroundStyleApple Developer Documentation
それぞれの表示は以下のようになります。(左が foregroundColor、右が、foregroundStyleを使用したものです)
WordPress の都合(?)で サイズが違いますが、表示は同じです。
API として 一見、名前が変わっただけに見えますが、実は引数の型が異なります。
.foregroundColor は、Color型 を受け取りますが、.foregroundStyle は、ShapeStyle 型 を受け取ります。
この .foregroundStyle の受けとる型である ShapeStyle を理解するのがこの記事の目標です。
ShapeStyle
参考
ShapeStyleApple Developer Documentation
説明には、”A color or pattern to use when rendering a shape.” と書かれていて、直訳すると、”形を描画するときに使用される色やパターン”となります。
.foregroundColor では、引数が Color でしたから 色しか 指定できませんでしたが、ShapeStyle を受け取るようになるということは、上の説明から考えるに、色だけでなく 描画パターン も指定できるようになるということです。
static に用意されている ShapeStyle
よく使用されるであろう ShapeStyle は、static 変数として用意されています。
以降の使用例では ShapeStyle がわかりやすいように、Rectangle を 使用しています。
Color/色 指定
単色で塗りつぶす ShapeStyle として以下が用意されています。
・black/blue/brown/clear/cyan/gray/green/indigo/mint/orange/pink/purple/red/teal/white/yellow
すでに、最初の例でも使用しましたが、以下のように ShapeStyle として、 .red や .green を指定でき、その色で描画することになります。
Rectangle().frame(width: 100, height: 100)
.foregroundStyle(.red)
Gradient/グラデーション指定
グラデーションについては、作り方別に 以下の ShapeStyle が用意されています。
・angularGradient/conicGradient/ellipticalGradient/linearGradient/radialGradient
linearGradient を使ってみます。見やすいように、Rectangle を使っています。
Rectangle().frame(width: 100, height: 100)
.foregroundStyle(.linearGradient(colors: [.red, .blue], startPoint: .leading, endPoint: .trailing))
Material/ 透明度指定
透明度に関しては、以下の ShapeStyle が用意されています。
・ultraThinMaterial/ thinMaterial/ regularMaterial/ thickMaterial/ ultraThickMaterial/ bar
透明 <- —- -> 不透明
ultraThinMaterial < thinMaterial < regularMaterial < thickMaterial < ultraThickMaterial
ツールバー向け
bar
thinMaterial を使ってみます。
Rectangle().frame(width: 100, height: 100)
.foregroundStyle(.thinMaterial)
Image/ 画像指定
イメージ/画像を使用するために、以下の ShapeStyle が用意されています。
・image
指定イメージが描画されるのではなく、付与された View の描画に 指定イメージが使用されるということです。
以下のような画像を用意して、使ってみます。使用した画像の解像度は、64×64 です。
Rectangle ではなく、Circle の描画に指定してみます。(元の画像が、64×64 なので、わかりやすくするために、256×256 指定しています)
Circle().frame(width: 256, height: 256)
.foregroundStyle(.image(Image("moru64_64")))
イメージをクリップしているのではなく、あくまで 指定されたイメージを使って、Circle を描画していることがわかるかと思います。
Hierarchical/ 構造からの指定
階層構造に応じたスタイルを指定するために、以下の ShapeStyle が用意されています。
・primary/secondary/teriary/quaternary/quinary
違いがわかりやすいように、全て並べてみました。
Rectangle().frame(width: 100, height: 100)
.foregroundStyle(.primary)
Rectangle().frame(width: 100, height: 100)
.foregroundStyle(.primary)
Rectangle().frame(width: 100, height: 100)
.foregroundStyle(.tertiary)
Rectangle().frame(width: 100, height: 100)
.foregroundStyle(.quaternary)
Rectangle().frame(width: 100, height: 100)
.foregroundStyle(.quinary)
Semantic/ 意味からの指定
意味的なスタイルを指定するために、以下の ShapeStyle が用意されています。
・foreground/ background/ selection/ separator/ tint/ placeholder/ link/ fill/ windowBackground
例えば、selection を指定すると、プラットフォームに応じた選択状態の描画になります。
以下では、placeholder を使ってみています。
比較のために、foregroundStyle なしの Rectangle も並べて表示します。(上が placeholder 指定、下は指定なし です。)
Rectangle().frame(width: 100, height: 100)
.foregroundStyle(.placeholder)
Rectangle().frame(width: 100, height: 100)
ShapeStyle protocol
protocol ShapeStyleに準拠させることで、 ShapeStyle を自分で用意して使用することもできます。
実装すべき メソッドは以下です。
func resolve(in environment: EnvironmentValues) -> some ShapeStyle
ありがちですが、ライトモード/ダークモードで異なる色を使用する ShapeStyle を作ってみます。
ライトモードでは black.opacity(0.8) を、ダークモードでは white.opacity(0.8) を使用する ShapeStyle です。
struct MyShapeStyle: ShapeStyle {
func resolve(in environment: EnvironmentValues) -> some ShapeStyle {
if environment.colorScheme == .light {
return Color.black.opacity(0.8)
} else {
return Color.white.opacity(0.8)
}
}
}
簡単に使えるように、extension に static で定義しておきます。
extension ShapeStyle where Self == MyShapeStyle {
static var myShapeStyle: MyShapeStyle {
MyShapeStyle()
}
}
以下のようなコードを使います。比較用に、ShapeStyle を指定しない Text も配置しています。
struct ContentView: View {
@State var blend = true
var body: some View {
VStack {
Text("Hello (no ShapeStyle)")
Text("Hello (MyShapeStyle)")
.foregroundStyle(.myShapeStyle)
}
.padding()
}
}
custom ShapeStyle conform to View
カスタム ShapeStyle を View にも準拠させると View としても使えるようになります。
さきほど作成した MyShapeStyle を View としても使えるように拡張します。
extension MyShapeStyle: View {
var body: some View {
Circle()
.foregroundStyle(self)
}
}
Circle を表示して、MyShapeStyle で 描画するようにしていますが、Circle を選んだ理由は特にありません。
ポイントは、View に conform させ body を定義すると、その View が 使用されるという点です。
つまり、以下のように MyShapeStyle が使用できるようになります。
struct ContentView: View {
var body: some View {
VStack {
MyShapeStyle()
}
.padding()
}
}
まとめ
ShapeStyle について、確認しました。
- 描画するときに使用される 型
- さまざまな Style が static に用意されている
- protocol ShapeStyle に conform させることで、独自の ShapeStyle を定義できる
- 独自 ShapeStyle も View に conform させると、View としても使用できる
説明は以上です。
不明な点やおかしな点ありましたら、こちらまで。
SwiftUI おすすめ本
SwiftUI を理解するには、以下の本がおすすめです。
SwiftUI ViewMatery
SwiftUI で開発していくときに、ViewやLayoutのための適切なmodifierを探すのが大変です。
英語での説明になってしまいますが、以下の”SwiftUI Views Mastery Bundle”という本がビジュアル的に確認して探せるので、便利です。
英語ではありますが、1ページに コードと画面が並んでいるので、非常にわかりやすいです。
View に適用できる modifier もわかりやすく説明されているので、ビューの理解だけではなく、どのような装飾ができるかも簡単にわかります。
超便利です
販売元のページは、こちらです。
SwiftUI 徹底入門
# SwiftUI は、毎年大きく改善されていますので、少し古くなってしまいましたが、いまでも 定番本です。
Swift学習におすすめの本
詳解Swift
Swift の学習には、詳解 Swift という書籍が、おすすめです。
著者は、Swift の初期から書籍を出していますし、Swift の前に主力言語だった Objective-C という言語についても同様の書籍を出しています。
最新版を購入するのがおすすめです。
現時点では、上記の Swift 5 に対応した第5版が最新版です。
Sponsor Link