【SwiftUI】Color とは一体何なのか

ふと思ったのですが。


Color
  .red
  .frame(width: 200, height: 200)

ただの「色」なのに、

「縦横寸法が指定できる」

「枠や対象がないのに表示される」

なんだか気持ち悪くないですか。

一体何者なんだ。

 

🎨 何者であるかの種類

思いつくものを、いくつか挙げておきます。

このうちのどれかだと思います。

View
A type that represents part of your app’s user interface and provides modifiers that you use to configure views.
アプリのユーザーインターフェイスの一部を表し、ビューの設定に使用する修飾子を提供するタイプ。

👉 View | Apple Developer Documentation hatena-bookmark

Shape
A 2D shape that you can use when drawing a view.
ビューを描くときに使用できる2D形状。

👉 Shape | Apple Developer Documentation hatena-bookmark

ShapeStyle
A color or pattern to use when rendering a shape.
図形をレンダリングするときに使用する色またはパターン。

👉 ShapeStyle | Apple Developer Documentation hatena-bookmark

眺めてるとなんとなくわかります。

何者かの種類のことが

「Protocol」

だったのですね !

 

🎨 よく使うあれは何者なのか

ドキュメントの「Conforms To」のところを見ます。

よく使うやつを見てみます。

Text
A view that displays one or more lines of read-only text.


Conforms To
Equatable
Sendable
View // *

👉 Text | Apple Developer Documentation hatena-bookmark

→ Text は View。

Button
A control that initiates an action.


Conforms To
View // *

👉 Button | Apple Developer Documentation hatena-bookmark

→ Button は View。

VStack
A view that arranges its subviews in a vertical line.


Conforms To
View // *

👉 VStack | Apple Developer Documentation hatena-bookmark

→ VStack は View。

Circle
A circle centered on the frame of the view containing it.


Conforms To
Animatable
ChartSymbolShape
InsettableShape
Sendable
Shape // *
View // *

👉 Circle | Apple Developer Documentation hatena-bookmark

→ Circle は Shape であり、View でもある。

RoundedRectangle
A rectangular shape with rounded corners, aligned inside the frame of the view containing it.


Conforms To
Animatable
InsettableShape
Sendable
Shape // *
View // *

👉 RoundedRectangle | Apple Developer Documentation hatena-bookmark

→ RoundRectangle は Shape であり、View でもある。

Material
A background material type.


Conforms To
Sendable
ShapeStyle // *

👉 Material | Apple Developer Documentation hatena-bookmark

→ Material は ShapeStyle である。

では、

Color
A representation of a color that adapts to a given context.


Conforms To
CustomStringConvertible
Equatable
Hashable
Sendable
ShapeStyle // *
Transferable
View // *

👉 Color | Apple Developer Documentation hatena-bookmark

→ Color は、 ShapeStyle であり、View でもある !

 

🎨 まとめ

Color は、

Material のような塗りつぶし方法の「ShapeStyle」であり、

Text のような表示の具の 「View」 でもある。

だったのだ !

👉 The many faces of ShapeStyle in SwiftUI | Swift with Majid hatena-bookmark
👉 Every SwiftUI protocol explained | FIVE STARS hatena-bookmark


【SwiftUI】CardView のような GroupBox は本当に便利なのか

こういうやつが簡単に作れる。

👉 GroupBox | Apple Developer Documentation hatena-bookmark


GroupBox("Today's Menu") {
  VStack(alignment: .leading) {
    Text("🍛 curry and rice")
    Text("🥗 green salad")
  }
}
.frame(width: 300)

 

🧑🏻‍💻 作ってみた

手作りと比較します。




VStack {
  HStack {
    Text("Today's Menu")
      .bold()
    Spacer()
  }
  VStack(alignment: .leading) {
    Text("🍛 curry and rice")
    Text("🥗 green salad")
  }
}
.padding()
.frame(width: 300)
.background(
  .background.secondary,
  in: .rect(cornerRadius: 8)
)

かなりコード量に差が出ますね。

 

🧑🏻‍💻 まとめ

便利ですね。

厳しいレイアウトの制限がない限り、

使う機会は多いかもしれません。

ちなみに、macOS で見てみると、

手書きのほうが意図通りとなりました。

少し残念。

👉 【SwiftUI】Default background Color in built-in View Component hatena-bookmark
👉 【SwiftUI】市松模様を背景にする - Checkered Pattern Background 🏁 hatena-bookmark
👉 【SwiftUI】四角の角を丸くする方法あれこれ hatena-bookmark
👉 【SwiftUI】 iOS / macOS の レイアウト記述を typealias で切り替える hatena-bookmark


【SwiftUI】市松模様を背景にする - Checkered Pattern Background 🏁

既存 View の 背景色。

分からないときありません ?

白なのか、グレーなのか、

透過しているのか、マテリアル的なやつなのか。

 

🏁 市松模様 Checkered Pattern

作っておきます。


struct CheckeredPattern: View {
  var size: CGFloat

  var body: some View {
    GeometryReader { gr in
      Grid(horizontalSpacing: 0, verticalSpacing: 0) {
        ForEach(0 ..< Int(ceil(gr.size.height / size)), id: \.self) { y in
          GridRow {
            ForEach(0 ..< Int(ceil(gr.size.width / size)), id: \.self) { x in
              (x % 2 == y % 2 ? Color.gray : Color.white)
                .frame(width: size, height: size)
                .opacity(0.25)
            }
          }
        }
      }
    }
  }
}

🏁 市松模様 - Checkered Pattern

 

🏁 Preview で使う


struct BackgroundCheckeredPattern<Content: View>: View {
  var size: CGFloat
  @ViewBuilder var content: () -> Content

  var body: some View {
    ZStack {
      CheckeredPattern(size: size)
        .edgesIgnoringSafeArea(.all)
      content()
    }
  }
}

 

🏁 extension 化

Preview などで使いやすように extension にしておきます。


extension View {
  func backgroundCheckeredPattern(size: CGFloat) -> some View {
    ZStack {
      CheckeredPattern(size: size)
        .edgesIgnoringSafeArea(.all)
      self
    }
  }
}

特に modifier まで作ることはないですね。


Button("Button") {
}
.buttonStyle(.bordered)
.controlSize(.extraLarge)
.backgroundCheckeredPattern(size: 15) // *

🏁 市松模様 - Checkered Patter

 

🏁 まとめ

サンプルコードとして Gist 化しておきます。



List の背景って .scrollContentBackground(.hidden) で消すんですね。

List の背景って .scrollContentBackground(.hidden) で消す

便利に使えるコードはたくさん持っておきたいです。