Swift5.1.3 Xcode11.3 SwiftUI
- オリジナルの単語帳アプリを自作します
- エクセルをCSV化する場合は改行コードなどあるので注意です
- 配列と辞書を使ってPickerに反映します
「以下は動画のハイライトです。」
自分でオリジナルの単語帳アプリを作ることは長年の夢でもありました。私がアプリを作るきっかけになったのも単語帳アプリを自作したいとの願望によるものでした。
プログラミングを少し勉強してみると基本の部分は意外に簡単に作成できてしまうので、この作り方を元にいろいろ応用していただければと思います。
まず例として果物の英単語を日本語で辞書的にCSVファイルにまとめたものをアプリに取り込む方法からお伝えします。NumbersやエクセルをCSV変換する場合は予期せぬ改行コードが入り不具合を起こすことがありますのでご注意ください。適宜改行コードを処理するか以下のコマンドなどでターミナルでの作成なら大丈夫です。データが多い場合はループなど使って単語帳の原型のCSVファイルを作ってください。
cd Desktop;
echo apple,リンゴ >> file.csv;
XcodeへのCSVファイルの取り込み方法は動画をご査収ください。
今回使う変数は以下のとおりです。
@State var csvArr = [String]()
@State var fluits = [String]()
@State var WordBook:Dictionary<String,String> = [:]
@State var selection:String = ""
@State var showPicker = false
またこれまで使ってきた以下のPickerも使用します。
struct SinglePicker: View {
let fluits: [String]
@Binding var selection:String
var body: some View {
GeometryReader { geometry in
Picker(" WordBook", selection: self.$selection) {
ForEach(0..<self.fluits.count) { row in
Text(verbatim: self.fluits[row]).tag(self.fluits[row])
}
}
}
}
}
CSVファイルの取り込みコードはVStackに以下を付属して起動時に実行します。
.onAppear(
perform: {
let url = Bundle.main.path(forResource: "file", ofType: "csv")
do {
var csvString = try String(contentsOfFile: url!, encoding: String.Encoding.utf8)
self.csvArr = csvString.components(separatedBy: .newlines)
self.csvArr.removeLast()
} catch let error as NSError {
print("Error: \(error)")
return
}
for sstr in self.csvArr {
let arrayPart = sstr.components(separatedBy: ",")
self.fluits.append(arrayPart[0])
self.WordBook[arrayPart[0]] = arrayPart[1]
}
}
)
CSVファイルがまず一行ずつ取り込まれてcsvStringとして配列化します。
その配列の要素はカンマを含みますのでカンマで分断するのが以下のコードとなります。
let arrayPart = sstr.components(separatedBy: ",")
分断した各要素はPicker用にfluitsの配列に利用される一方で、WordBookの辞書も同時に作成します。
するとPickerで選択したものが辞書で引用されて英単語と日本語を同時に表示してくれるようになります。
これをVStack内で以下のように配置します。
Button(action:{
self.showPicker.toggle()
}) {
Text("Load CSV")
}
Text("\(self.selection)").foregroundColor(.red)
Text("\(self.WordBook[self.selection] ?? "")")
if showPicker {
SinglePicker(fluits: fluits, selection: $selection)
} else {
SinglePicker(fluits: fluits, selection: $selection)
}
この中で苦戦したことがSinglePicker()がCSVファイルの取り込み前に作成されてしまうことでした。SwiftUIではPickerを後から更新する手段が意外に情報がなくスマートに行う術がわかりませんでした。
UIPickerViewなどではreloadAllComponents()など便利なfunctionがPickerViewに用意されているのですがSwiftUIにももしかしたら同じようなものがあるかもしれません。
私の方で発見したPickerを更新する方法としてはButtonのActionで更新するというものです。SinglePickerをもともと二つ用意してtoggle()で切り替えて新しいものを別途作り直すという荒技です。
もっといい方法もあるかもしれませんので何か良い方法をご存知な方がいらっしゃいましたらご教示いただけると幸いです。
ソースコードはYouTubeのコメント欄に記載します。
目次へ戻る