【SwiftUI】pickerの選択肢ごとに色を変えたかった
あまりプログラミングをしないエンジニアなのですが、SwiftUIが良さそうというのを聞いたので最近趣味感覚で書いています。
今回はpickerの選択肢ごとに色を変えたかったのでやってみました。
完成形はこんな感じです。
どうやるかなのですが、今回はjsonファイルで色を設定してみました。(もっと良い方法あるかもしれないです。。)
まずこんな感じのjsonファイルを用意します。idとname以外は色の設定値です。 ファイル名はAlphabets.jsonにします
{ "alphabets":[ { "id": 1, "name": "A", "hue": 0.476, "saturation": 0.075, "brightness": 0.041, "opacity": 0.227 }, { "id": 2, "name": "B", "hue": 0.476, "saturation": 0.78, "brightness": 0.929, "opacity": 0.532 }, { "id": 3, "name": "C", "hue": 0.32, "saturation": 0.751, "brightness": 0.565, "opacity": 0.962 }, { "id": 4, "name": "D", "hue": 0.845, "saturation": 0.961, "brightness": 0.952, "opacity": 0.962 }, { "id": 5, "name": "E", "hue": 0.177, "saturation": 0.921, "brightness": 0.977, "opacity": 0.962 },
次はjsonデータをデコードします。
新たに下記のswiftファイルを作成します。
import Foundation let mojis:[Alphabet] = getJson() struct Mojis: Codable { var alphabets: [Alphabet] } struct Alphabet: Codable { var id: Int var name: String var hue: Double var saturation: Double var brightness: Double var opacity: Double } func getJson() -> [Alphabet] { guard let path = Bundle.main.path( forResource: "Alphabets", ofType: "json") else { fatalError("Couldn't find json file") } let url = URL(fileURLWithPath: path) guard let json = try? Data(contentsOf: url) else { fatalError("parse error") } let decoder = JSONDecoder() let decodeData: Mojis do { decodeData = try decoder.decode(Mojis.self, from: json) } catch { fatalError("decode error") } return decodeData.alphabets }
何をしているかというと まず、上の2つのstructはjsonファイルに合わせて作成します
そして次に、下記の様にjsonファイルを読み込んでいます
guard let path = Bundle.main.path( forResource: "Alphabets", ofType: "json")
次にjsonデータをデコードしています
guard let json = try? Data(contentsOf: url) else { fatalError("parse error") } let decoder = JSONDecoder() let decodeData: Mojis do { decodeData = try decoder.decode(Mojis.self, from: json) } catch { fatalError("decode error") }
これでデータを加工できたので、次に表示していきます。
XcodeでSwiftUIのプロダクトを作成するとContentView.swiftファイルが作成されていると思うので、そこを編集していきます。
最初はこの様な感じになっています。
ContentView.swift
なので下記の様に修正しました
import SwiftUI struct ContentView: View { @State private var selected = "" var body: some View { VStack { Picker(selection: $selected, label: Text("アルファベット")) { ForEach(0..<15) { num in Text(mojis[num].name) .font(.body) .frame(width: 200.0, height: 20.0) .background(Color( hue: mojis[num].hue, saturation: mojis[num].saturation, brightness: mojis[num].brightness, opacity: mojis[num].opacity)) .tag(mojis[num].name) } } Text("選択した文字: \(selected)") } }
この@Stateをつけると値を監視して、変更されると更新してくれます
@State private var selected = ""
そしてあとはPickerの使い方ですがこちらのサイトを参考にしました。
こんな感じで作成しました。
説明が雑になってしまったのですが、アドベントカレンダーで今日までということを忘れていました。。
SwiftUIは書いてて楽しいので、また書いていきたいです!
ちなみにこちらの本を参考にしました。
SwiftUIではじめるiPhoneアプリプログラミング入門 | 大津 真 |本 | 通販 | Amazon
それでは〜