##はじめに
少し前のことになりますが、先日初めてSwiftUIを使ってマンセルカラーをRGBに変換するアプリ「色検索」をリリースすることができました。
アプリがリリースされわずかでもインストールされ使ってくれる人がいることは大変嬉しいのですが、リリースまでには個人で開発することの難しさ、さらに技術として新しいSwiftUIを用いて開発を行うことはなかなか大変でした。
自分がどのようにアプリをリリースまでに至ったのかをまとめたいと思います。自分と同じようにアプリ開発をしたい!SwiftUIを使ってみたい!という人の参考jになれば幸いです。
##「色検索」の紹介
###①マンセルカラーシステムから色を探せる
CSSでUIColorなどで色を決定する時、RGBピッカーやスライダーによって決定することが多く、極端な色になりがちです。特に最近流行りのパステルカラーや「エモい」色合いなどをRGB値でピンポイントに作り出すことは難しいと思います。そこで細かに色が整理されたマンセルカラーからRGBが分かれば便利なのではないかと考えました。初めに表示される画面は影をつけたり立体的にスライドされるSWiftUIらしい(?)デザインにしました。
###②検索後はRGB値の微調整、カラーコードの取得ができる。
好みの色にたどり着いた後はRGBスライダーで微調整をすることとカラーコードを取得することが可能です。カラーコードは長押しでコピーすることもできます。
##③色をストックしておくことができる。
保存するボタンを押すことで端末に保存され、いつでも色を取り出すことができます。(コピーは保存画面でも検索された色の画面でも両方できます。)
##④スライダーから色をつくることもできる。
検索画面に表示される色だけで 全ての色が載せ切れているわけではありません。スライダーから色を作り出すことも可能です。
##全体の構成
初心者ながらに感じるSwiftUIの良さとして、「抽象的に定義すれば使いまわせる」というものがあります。上の写真の通り、アプリには小さな長方形がたくさん出てきますが、それは一つひとつ作っているのではありません。
###最も小さい構造体
import SwiftUI
struct ColorCell: View {
var rValue: Int
var gValue: Int
var bValue: Int
var body: some View {
NavigationLink(destination: ColorSlider(R: Double(rValue), G: Double(gValue), B: Double(bValue))) {
Text("")
.frame(width: 30, height: 35)
.background(Color.init(UIColor(rValue,gValue,bValue)))
.cornerRadius(8)
.shadow(color: Color.gray.opacity(0.7), radius: 5.0, x: 0.0, y: 0.0)
}
}
}
struct ColorCell_Previews: PreviewProvider {
static var previews: some View {
ColorCell(rValue: 0, gValue: 0, bValue: 0)
}
}
最も小さい集合となるColorCellと定義した構造体を定義します。ColorCellを呼び出すには
var rValue: Int var gValue: Int var bValue: Int
の3つを同時に定義しなければなりません。
例ColorCell(rValue: 0, gValue: 0, bValue: 0)
###2番目に小さい構造体
import SwiftUI
struct ColorValue: View {
var colorArray: [[Int]]
var body: some View {
VStack {
HStack {
VStack(spacing: 5.0) {
Spacer()
ForEach(0..<colorArray.count, id: \.self){ j in
ColorCell(rValue: self.colorArray[j][0], gValue: self.colorArray[j][1], bValue: self.colorArray[j][2])
}
}
}
}
}
}
struct ColorValue_Previews: PreviewProvider {
static var previews: some View {
ColorValue(colorArray: ColorDataR[0].v9)
}
}
次にVStack
の中に先ほど定義したColorCell
を入れることでColorCellを鉛直方向に並べます。ColorArray
はRGB値が入った2次元配列です。ColorValue
を呼び出すためには2次元配列ColorValue
を定義しなければなりません。
###3番目に小さい構造体
import SwiftUI
struct MunsellColorTable: View {
var colorData: colorData
var body: some View {
VStack {
HStack {
ColorValue(colorArray: colorData.v9)
ColorValue(colorArray: colorData.v8)
ColorValue(colorArray: colorData.v7)
ColorValue(colorArray: colorData.v6)
ColorValue(colorArray: colorData.v5)
ColorValue(colorArray: colorData.v4)
ColorValue(colorArray: colorData.v3)
ColorValue(colorArray: colorData.v2)
ColorValue(colorArray: colorData.v1)
}
Spacer()
Spacer()
.navigationBarTitle("\(colorData.name)")
}
}
}
struct MunsellColorTable_Previews: PreviewProvider {
static var previews: some View {
MunsellColorTable(colorData: ColorDataR[0])
}
}
MunsellColorTable
はColorCell
を鉛直方向に並べたColorValue
を水平方向に並べたものです。HStack
の中にColorValue
が並べられています。
MunsellColorTable
を呼び出すためにはColorData
型のcolorDataを定義する必要があります。
###4番目に小さい構造体
一つの画面ができたので、それらを水平方向に並べます。コードは割愛しておりますが、これもHStack
の中に先ほど作った`MunsellColorTable'が並べられています。
###5番目に小さい構造体(最も大きい構造体)
お疲れ様でした。上で定義した構造体をVStack
で並べれば完成です。R,YR,Y...と色は続きますが、全てそれぞれの色のRGB値のJSONデータと細分化された構造体で作られています。
##色を選択した画面
ColorCell
をタップするとそれぞれのRGB値やカラーコードが表示された画面へ移動します。この画面も小さな構造体をVStack
で並べて作られています。
##技術を得るために
###教材
SwiftUIは新しい技術であるので、学習教材が多いとはいえません。僕はSwiftUIのチュートリアルを最も参考にしました。ただ、英語で説明されているので、日本語訳された超初心者のためのSwiftUIチュートリアルにも大変お世話になりました。SwiftUIを使ったアプリ開発をしているYoutube動画も参考にしました。
###Qiitaでのアウトプット
SwiftUIの技術記事はめちゃくちゃ少ないです。備忘録・アウトプットによる定着などの意味を込めて記事はたくさん書きました。
[SwiftUIで画像を表示する(画像の切り抜きと影)]
(https://qiita.com/Hyperbolic_____/items/aaa9171e81c1683b35a8)
SwiftUIの基本となるHStack,VStack
SwiftUIで画像とテキストを表示する(チュートリアル)
SwiftUIでList(TableView)を作る
SwiftUIでNavigationController(NavigationView)
SwiftUIでNavigationVarとListの組み合わせ
SwiftUIのAlignment構造体について
@State について
SwiftUIでForEachを使う時につまづいた話
SwiftUI でオブジェクトを回転させる方法
SwiftUIで画面の左上にビューを配置する方法
SwiftUIで大量のボタン等を設置する方法
SwiftUIで「式が複雑すぎる」「式を分解しろ」と言われたら
SwiftUIでNaivigationViewが重なったら
SF symbolsの使い方
SwiftUIでScrollViewするときに影が横に出ないなどのトラブル対処法
###Teratailでの質問
どうしてもエラーが解決できない時はエンジニア質問サイトTeratailで質問しました。JSONファイルの作り方など振り返ると基本的なことも質問していました。笑
SwiftUIでForEachを使う時にエラーが出る時の対処方法
jsonファイルの作り方
Swiftで多重for文を回避したい
SwiftUIのNavigationLinkで画像がグレーアウトしてしまう
[SwiftUI]UserDefaultsによってデータの永続化をしたい
[SwiftUI] GeometryReaderを使ったものをScrollViewで並べると位置がずれてしまう
[SwiftUI].gesture(LongPressGesture)や.onLongPressGestureを使うとスクロールできなくなる
[SwiftUI] Sliderがある値以上で動かなくなる
##終わりに
ここまで読んでくださりありがとうございました。teratailで質問に答えてくれる方、公式チュートリアルを日本語訳してくれる方、Youtubeで動画を上げてくださる方..様々な方のおかげで開発を継続できました。自分がQiita記事を投稿するのもそういった技術の共有が大事だと感じているからです。これからも勉強を続けていきます!