# Swatch

[swift](../../swift)⟩ [custom](..) ⟩ [view]() ⟩ Swatch

{% hint style="info" %}
可顯示<mark style="color:yellow;">一小塊展示區</mark>與<mark style="color:yellow;">名稱</mark>的色卡，但不止於顯示顏色，任何 view 都可以。
{% endhint %}

<figure><img src="https://1830103165-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M5-JmwCZMKh_d7RfBaN%2Fuploads%2FyMldJJbYYD34JV1H9Hwk%2Fswatches.jpeg?alt=media&#x26;token=0402f396-bf81-4c90-80cf-3f27293f412e" alt=""><figcaption><p>swatches</p></figcaption></figure>

{% tabs %}
{% tab title="💾 程式" %}
```swift
import SwiftUI

struct Swatch<V: View>: View {
    
    // font: Avenir Next Condensed
    let avenir = Font.custom("AvenirNextCondensed-Regular", size: 14)
    
    let size: CGFloat    // swatch size
    let name: String     // view name
    
    let shadow: Color    // border inner shadow
    let border: Color    // border color
    
    let view: () -> V     // swatch view
    
    init(
        name   : String,
        size   : CGFloat = 80, 
        shadow : Color = .bg2,     // 🌀 Color + system colors
        border : Color = .bg3,
        view: @escaping () -> V
    ){
        self.size = size
        self.name = name
        self.shadow = shadow
        self.border = border
        self.view = view
    }
    
    var body: some View {
        VStack(spacing: 0) {
            
            // swatch view
            view()
                // ⭐️ overlay shadow + blend
                .overlay {
                    Rectangle()
                        .fill(.white.shadow(.inner(
                        color: shadow, radius: 2, x: 2, y: -2
                    )))
                        // ⭐️ 必須用 .blendMode() 否則填充色會蓋住前景
                        .blendMode(.multiply)
                }
                .frame(width: size, height: size)
                .border(border)    
            
            // swatch name
            // 不要直接用 Text，否則會因為 Text 的長度不一而影響版面❗️
            Rectangle()
                .fill(.clear)
                .frame(width: size, height: 20)
                .overlay {  
                    Text("\(name)")
                        .font(avenir)
                        .fixedSize()    // ⭐️ no wrap
                }
        }
        .padding(4)
        .border(border)
    }
}// Swatch<V>
```
{% endtab %}

{% tab title="👥 相關" %}
* [swatch\_0](../ext/color+/system/swatch_0 "mention")：舊的色卡設計
* [shadow](../../swiftui/view/drawing/shadow "mention")：色卡有<mark style="color:yellow;">內陰影</mark>的設計
{% endtab %}

{% tab title="💈範例" %}
```swift
// example
struct SwatchExample: View {
    let colors = Color.standardColors.first(11)    // 🌀 Array + .first(_ size:)
    var body: some View {
        VStack(spacing: 16) {
            // colors
            HStack(spacing: 12) { ForEach(colors, id: \.self) { color in
                Swatch(name: color.name, border: .label4) { color } // 👔 custom view
            }}
            // gradient of colors
            HStack(spacing: 12) { ForEach(colors, id: \.self) { color in
                Swatch(name: "\(color.name).gradient", border: .label4) { color.gradient }
            }}
        }// VStack
    }// body
}

// previews
struct Swatch_Previews: PreviewProvider {
    static var previews: some View {
        SwatchExample()
    }
}
```
{% endtab %}

{% tab title="⬆️ 需要" %}
* [arr.first](../../swift/type/category/basic/array/arr.first "mention")： array first n elements
* [system](../ext/color+/system "mention")： 色卡顏色來源
{% endtab %}
{% endtabs %}
