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)
}
}
}
}
}
コードのダウンロード
今回の記事で作成したコードのダウンロードはこちらです。