第10回 カラーピッカーの仕上げ | SwiftUIでカラーピッカーを作る

SwiftUIでカラーピッカーを作る連載記事です。前回まででカラーピッカー自体は完成です。今回は作ったカラーピッカーを実際に使って見るサンプルアプリを作って仕上げとします。

目次

作る内容

“Hello World”のラベルとボタンを表示し、ボタンがタップされたらカラーピッカーを表示します。カラーピッカーで色を変更すると、Hello Worldのラベルの文字色をカラーピッカーの色に変更します。

モデルの実装

サンプルアプリ用のモデルクラスを作ります。

ColorPickerAppModelの実装

このサンプルアプリは単純に文字色を管理するだけです。次のようなモデルクラスを作りました。

import SwiftUI

class ColorPickerAppModel : ObservableObject {
    @Published var textColor: Color = .black
}

EnvironmentObjectにする

ColorPickerAppModelクラスはアプリの情報を管理して、そのインスタンスにはアプリ全体からアクセス出来るのが適切です。このようなオブジェクトをSwiftUIではEnvironmentObjectにします。

import SwiftUI

@main
struct ColorPickerApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
                .environmentObject(ColorPickerAppModel())
        }
    }
}

メイン画面の実装

メイン画面を実装します。メイン画面は「Hello World」と表示されたラベルを一つと、カラーピッカーを表示するためのボタンを一つ配置します。

ラベルの配置

ラベルは大きめの文字で、ColorPickerAppModel.textColorを文字色に設定します。ColorPickerAppModelはEnvironmentObjectなので、@EnvironmentObjectでアクセス出来ます。@EnvironmentObjectと書いてプロパティを定義すると、.environmentObjectモディファイアで設定したインスタンスにアクセス出来ます。

ColorPickerApp.swiftでEnvironmentObjectに設定したインスタンスはアプリ実行時に使われます。
XcodeのライブプレビューではContentView_Previews.previews内で実行しているenvironmentObject()に渡したインスタンスが使われます。
違いに注意です。

import SwiftUI

struct ContentView: View {
    @EnvironmentObject var model: ColorPickerAppModel
    
    var body: some View {
        VStack {
            Text("Hello World")
                .font(.largeTitle)
                .foregroundColor(model.textColor)
                .padding()
            Button("Change Color") {
                
            }
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
            .environmentObject(ColorPickerAppModel())
    }
}

カラーピッカーの呼び出し

前回までに実装したカラーピッカーを使って、文字色を変更する機能を作ります。

カラーピッカーの表示状態の管理

カラーピッカーを表示するためのコードを追加します。SwiftUIでは表示されているという状態を管理する設計にします。カラーピッカーが表示されている状態を管理するプロパティをContentViewに追加します。

「表示されている状態を管理する」という考え方がUIKitと大きくことなる特徴です。

struct ContentView: View {
    @EnvironmentObject var model: ColorPickerAppModel
    
    @State private var isColorPickerPresented: Bool = false

カラーピッカーを表示する

カラーピッカーを表示するには、表示状態を管理するisColorPickerPresentedプロパティをtrueに変更します。それを元にモーダル表示するにはsheetモディファイアを使用します。sheetモディファイアでColorPickerを表示します。

また、ColorPickerのイニシャライザにはColorPickerModelが必要です。カラーピッカーを表示するところだけ必要なので、ColorPickerAppModelに追加するのは違うかなと思います。そこで、ContentViewにプロパティを追加します。

import SwiftUI

struct ContentView: View {
    @EnvironmentObject var model: ColorPickerAppModel
    
    @State private var isColorPickerPresented: Bool = false
    @StateObject var colorPickerModel: ColorPickerModel = ColorPickerModel()
    
    var body: some View {
        VStack {
            Text("Hello World")
                .font(.largeTitle)
                .foregroundColor(model.textColor)
                .padding()
            Button("Change Color") {
                self.isColorPickerPresented = true
            }
            .sheet(isPresented: $isColorPickerPresented) {
                ColorPicker(model: colorPickerModel)
            }
        }
    }
}

ColorPickerAppModel.textColorの更新

カラーピッカーで設定された色をColorPickerAppModel.textColorに代入する処理を実装します。カラーピッカーが閉じられるときに、ColorPickerAppModelのプロパティに入っている値を取得して、textColorプロパティを更新します。閉じられるときに、何か処理を行うには、onDisappearモディファイアを使用します。

struct ContentView: View {
    @EnvironmentObject var model: ColorPickerAppModel
    
    @State private var isColorPickerPresented: Bool = false
    @StateObject var colorPickerModel: ColorPickerModel = ColorPickerModel()
    
    var body: some View {
        VStack {
            Text("Hello World")
                .font(.largeTitle)
                .foregroundColor(model.textColor)
                .padding()
            Button("Change Color") {
                self.isColorPickerPresented = true
            }
            .sheet(isPresented: $isColorPickerPresented) {
                ColorPicker(model: colorPickerModel)
                    .onDisappear() {
                        self.model.textColor = Color(red: self.colorPickerModel.red, green: self.colorPickerModel.green, blue: self.colorPickerModel.blue)
                    }
            }
        }
    }
}
ContentViewのプレビューでカラーピッカーを表示しているところ

コードのダウンロード

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

連載目次

著書紹介

よかったらシェアしてね!
  • 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

目次