第8回 選択色のプレビューを作る | SwiftUIでカラーピッカーを作る

SwiftUIでカラーピッカーを作る連載記事です。今回は前回までに作成したRGB各チャネルのスライダーで選択した値を元に色をプレビュー表示する処理を実装します。

また、現在値のフォーマットが小数点以下1桁になっているため、数値指定する場合の精度が低すぎます。文字列化のフォーマットも修正します。

目次

現在値の文字列化フォーマット変更

ColorPickerChannelModelクラスのfieldTextプロパティを修正します。次のように文字列化フォーマットを%.1fから%gに変更します。

    /// 入力中のテキストのバインディング
    var fieldText: Binding<String> {
        Binding {
            self.fieldTextStore ?? String(format: "%g", self.currentValue)
        } set: {
            self.fieldTextStore = $0
            if let value = Double($0) {
                self.changeCurrentValue(value)
            }
        }
    }
数値の表示を変更したプレビュー

色のプレビューの表示

選択された色をプレビュー表示する処理を実装します。

ColorPickerPreviewの実装

プレビューを表示するビューを実装します。プレビューはシンプルに次のような処理にします。

  • 選択色で塗りつぶす
  • 4pixel程度の枠を付ける

次のようなコードになります。

import SwiftUI

struct ColorPickerPreview: View {
    @Binding var color: Color
    
    var body: some View {
        GeometryReader { geometry in
            Path { path in
                path.addRect(CGRect(x: 0, y: 0, width: geometry.size.width, height: geometry.size.height))
            }
            .fill(color)
            
            Path { path in
                path.addRect(CGRect(x: 0, y: 0, width: geometry.size.width, height: geometry.size.height))
            }
            .stroke(lineWidth: 4)
        }
    }
}

struct ColorPickerPreview_Previews: PreviewProvider {
    static var previews: some View {
        ColorPickerPreview(color: .constant(.blue))
    }
}
ColorPickerPreviewのプレビュー

ColorPickerへの追加

ColorPickerColorPickerPreviewを配置します。配置場所は3つのPickerGradationViewの下に縦横50pixel程度で配置します。

ColorPickerPreview.colorプロパティに渡すバインディングを作ります。redChannel.currentValue, greenChannel.currentValue, blueChannel.currentValueからColorを作って、Binding<Color>で返すプロパティを追加します。

    var color: Binding<Color> {
        Binding {
            Color(red: redChannel.currentValue,
                  green: greenChannel.currentValue,
                  blue: blueChannel.currentValue)
        } set: { _ in
        }

    }

ColorPickerPreviewをビューに置きます。分かりやすいようにパッディングやラベルも一緒に置きます。

import SwiftUI

struct ColorPicker: View {
    @StateObject var redChannel: ColorPickerChannelModel = ColorPickerChannelModel(channelName: "Red")
    @StateObject var redGradation: ColorPickerGradationModel = .red
    
    @StateObject var greenChannel: ColorPickerChannelModel = ColorPickerChannelModel(channelName: "Green")
    @StateObject var greenGradation: ColorPickerGradationModel = .green
    
    @StateObject var blueChannel: ColorPickerChannelModel = ColorPickerChannelModel(channelName: "Blue")
    @StateObject var blueGradation: ColorPickerGradationModel = .blue
    
    var color: Binding<Color> {
        Binding {
            Color(red: redChannel.currentValue,
                  green: greenChannel.currentValue,
                  blue: blueChannel.currentValue)
        } set: { _ in
        }

    }
    
    var body: some View {
        VStack {
            ColorPickerSubView(channel: redChannel, gradation: redGradation)
            ColorPickerSubView(channel: greenChannel, gradation: greenGradation)
            ColorPickerSubView(channel: blueChannel, gradation: blueGradation)
            VStack {
                Text("Preview")
                ColorPickerPreview(color: color)
                    .frame(width: 100, height: 100)
            }
            .padding()
        }
        .padding()
    }
}

struct ColorPicker_Previews: PreviewProvider {
    static var previews: some View {
        ColorPicker()
            .previewInterfaceOrientation(.portrait)
    }
}
ColorPickerPreviewを配置したプレビュー

コードのダウンロード

今回の記事で作成したコードのダウンロードはこちらです。

連載目次

著書紹介

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

Akira Hayashi (林 晃)のアバター Akira Hayashi (林 晃) Representative(代表), Software Engineer(ソフトウェアエンジニア)

アールケー開発代表。Appleプラットフォーム向けの開発を専門としているソフトウェアエンジニア。ソフトウェアの受託開発、技術書執筆、技術指導・セミナー講師。note, Medium, LinkedIn
-
Representative of RK Kaihatsu. Software Engineer Specializing in Development for the Apple Platform. Specializing in contract software development, technical writing, and serving as a tech workshop lecturer. note, Medium, LinkedIn

目次