今回作成するアプリ
ColorPickerを使用し選択したColorをUserDefaultsに保存するにはどうすればいいでしょうか?
実はUserDefaultsが対応している型が限られており(Data、String、Number(Int、Float、Double)、Date、Array、Dictionary、Boolなど)、Color は保存できる型ではありません。
つまり、文字列や数値のように以下のような構文で単純に保存することはできません。
UserDefaults.standard.set(username, forKey: "username")
今回は、その非対応のColor型をUserDefaultsに保存し永続化する方法をご紹介します。
実装
コード
import SwiftUI
class ColorData {
private var COLOR_KEY = "COLOR_KEY"
private let userDefaults = UserDefaults.standard
func saveColor(color: Color) {
// Convert the color into RGB
let color = UIColor(color).cgColor
// Save the RGB into an array
if let components = color.components {
userDefaults.set(components, forKey: COLOR_KEY)
print("Colour saved!")
}
}
func loadColor() -> Color{
// Get the RGB array
guard let array = userDefaults.object(forKey: COLOR_KEY) as? [CGFloat] else { return Color.black }
// Create a color from the RGB array
let color = Color(.sRGB,
red: array[0],
green: array[1],
blue: array[2],
opacity: array[3])
print("Colour loaded!")
return color
}
}
struct ContentView: View {
@State private var color: Color = Color.black
private var colorData = ColorData()
var body: some View {
VStack(spacing: 10) {
ColorPicker("Pick a color:", selection: $color)
Rectangle()
.frame(height: 200)
.foregroundColor(color)
.cornerRadius(20)
.padding()
Button("Save colour") {
colorData.saveColor(color: color)
}
Spacer()
}
.onAppear {
color = colorData.loadColor()
}
.padding()
}
}
解説
RGBに変換し、それを配列に格納することで保存します。
取り出すときは、配列にそれぞれ格納されたRGBから再生させ、Color型に変換します。
“Save colour”のボタンを押すことでsaveColor()が発動しColorが保存されます。
また、.onAppear
によってViewが表示された際にloadColor()が発動するので、再度アプリを開くと自動的に保存した色が反映されています。
動作
参考文献
環境
macOS Ventura 13.0.1
Xcode 14.2
iOS 16.2
アイキャッチ画像 出典: App.com