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


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













