[SwiftUI] ShapeStyle を理解する

SwiftUI2021

     
⌛️ 4 min.

実際に動くコードを書いてみることで ShapeStyle の理解を深めます。

環境&対象

以下の環境で動作確認を行なっています。

  • 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を使用したものです)

colorRed
styleRed

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)
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))
linearGradient

Material/ 透明度指定

透明度に関しては、以下の ShapeStyle が用意されています。

・ultraThinMaterial/ thinMaterial/ regularMaterial/ thickMaterial/ ultraThickMaterial/ bar

透明 <- —- -> 不透明

ultraThinMaterial < thinMaterial < regularMaterial < thickMaterial < ultraThickMaterial

ツールバー向け

bar

thinMaterial を使ってみます。

Rectangle().frame(width: 100, height: 100)
    .foregroundStyle(.thinMaterial)
thinMaterial

Image/ 画像指定

イメージ/画像を使用するために、以下の ShapeStyle が用意されています。

・image

MEMO

指定イメージが描画されるのではなく、付与された View の描画に 指定イメージが使用されるということです。

以下のような画像を用意して、使ってみます。使用した画像の解像度は、64×64 です。

moru

Rectangle ではなく、Circle の描画に指定してみます。(元の画像が、64×64 なので、わかりやすくするために、256×256 指定しています)

Circle().frame(width: 256, height: 256)
    .foregroundStyle(.image(Image("moru64_64")))
image

イメージをクリップしているのではなく、あくまで 指定されたイメージを使って、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)
Hierarchical

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)
placeholder

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()
    }
}
lightMode
darkMode

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()
    }
}
ViewLight
ViewDark

まとめ

ShapeStyle について、確認しました。

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 もわかりやすく説明されているので、ビューの理解だけではなく、どのような装飾ができるかも簡単にわかります。

超便利です

SwiftUIViewsMastery

販売元のページは、こちらです。

SwiftUI 徹底入門

# SwiftUI は、毎年大きく改善されていますので、少し古くなってしまいましたが、いまでも 定番本です。

Swift学習におすすめの本

詳解Swift

Swift の学習には、詳解 Swift という書籍が、おすすめです。

著者は、Swift の初期から書籍を出していますし、Swift の前に主力言語だった Objective-C という言語についても同様の書籍を出しています。

最新版を購入するのがおすすめです。

現時点では、上記の Swift 5 に対応した第5版が最新版です。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です