前提・実現したいこと
現在支出管理アプリを作成しているのですが、その際、項目+利用金額という形で表示させています。
これを配列に格納して管理しているのですが、アプリを閉じても初期化されないようにUserDefaultsを使おうと考えています。
しかし、調べて試してもうまくいかず、行き詰まっています。
どなたかご教授いただけると助かります。
該当のソースコード
import SwiftUI struct ContentView: View { //タイトルバーの年月 @AppStorage("TitleYear") var titleYear = "yyyy" @AppStorage("TitleMonth") var titleMonth = "mm" //シートの状態 //年月変更シート @State var isShowDate: Bool = false //項目追加シート @State var isShowItem: Bool = false //各種インスタンス生成 @EnvironmentObject var userItemList: UserItemList var userDefaults = UserDefaults.standard var body: some View { NavigationView{ List{ ForEach(userItemList.itemList){ item in KomokuList(items: item.itemName, spendPrice: item.price) } //行削除操作時に呼び出す処理の指定 .onDelete(perform: rowRemove) } //タイトル .navigationBarTitle("(self.titleYear)" + "年" + "(self.titleMonth)" + "月の利用予定額", displayMode: .inline) //項目追加ボタンと年月変更ボタンを配置 .navigationBarItems(leading: Button(action: { isShowItem = true }){ Text("追加") }, trailing: Button(action: { isShowDate = true }) { Text("年月変更") }) .sheet(isPresented: $isShowDate){ DateChange(year: $titleYear, month: $titleMonth, isPresented: $isShowDate) } .sheet(isPresented: $isShowItem){ ItemAdd(isPresentedItem: $isShowItem) } } } //行削除処理 func rowRemove(offsets: IndexSet) { userItemList.itemList.remove(atOffsets: offsets) } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView(titleYear: "0000", titleMonth: "00") .environmentObject(UserItemList()) } }
//項目や金額を設定する import SwiftUI struct ItemAdd: View { @Binding var isPresentedItem: Bool @State var inputItem: String = "" @State var inputPrice: String = "" @EnvironmentObject var userItemList: UserItemList var body: some View { NavigationView{ VStack{ HStack { Text("利用品目名:") TextField("利用品目名を記入してください", text: $inputItem) } HStack { Text("利用予定額:") TextField("利用予定額を記入してください", text: $inputPrice).keyboardType(.numberPad) } Spacer() Button(action: { isPresentedItem = false }){ Text("キャンセル") } Button(action: { isPresentedItem = false self.createItem() }){ Text("追加") }.disabled(!inputValueCheck()) Spacer() } .navigationBarTitle("購入品目追加", displayMode: .inline) } } //利用品目名と利用予定額を生成する関数 func createItem(){ let newItem = KomokuData(itemName: self.inputItem, price: Int(self.inputPrice)!) self.userItemList.itemList.insert(newItem, at: 0) self.inputItem = "" self.inputPrice = "" } //入力値チェック //各項目が前後空白を除いて1文字以上ある場合trueを返す func inputValueCheck() -> Bool { inputItem.trimmingCharacters(in: .whitespacesAndNewlines).count >= 1 && inputPrice.trimmingCharacters(in: .whitespacesAndNewlines).count >= 1 } } struct ItemAdd_Previews: PreviewProvider { static var previews: some View { ItemAdd(isPresentedItem: Binding.constant(false)) .environmentObject(UserItemList()) } }
//各種データ管理 struct KomokuData: Identifiable { var id = UUID() var itemName:String var price:Int init(itemName: String, price: Int) { self.itemName = itemName self.price = price } }
//配列を管理 import swiftUI class UserItemList: ObservableObject{ @Published var itemList = [ KomokuData(itemName: "課金", price: 10000), KomokuData(itemName: "お菓子代", price: 3000), KomokuData(itemName: "漫画代", price: 1000) ] @Published var isEditing: Bool = false }
試したこと
下記のサイトを調べてみました
https://capibara1969.com/2531/#toc16
補足情報(FW/ツールのバージョンなど)
Xcode:12.5
UI:SwiftUI
投稿ボタンを押す前に、「配列保存の保存をして」という題名から自分の書いた内容を確認されたらどうでしょうか?
すみません。
ご指摘ありがとうございます。
userDefaultsを使って、どこで何を保存しているかの記載がないのではないですか?それとも、それも質問のうちですか?
そちらも質問のうちです。
僕が思っていたことは、ContentViewでuserDefaultsで保存するのかなと思っていたのですが、うまくできないため、どこで使えばいいのかという質問になります。
それは自分で検索すれば、答えがわかるような気がしますが。。。
まだswift始めて間もなく、分からないことだらけでした。
もう少し自分でやってみます。
KomokuDataのStructが間違っています。
そのようでした。
色々とご指摘していただきありがとうございます。
回答1件
あなたの回答
tips
プレビュー