質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Swift Playgrounds

Swift Playgroundsは、初心者・子ども向けのSwift学習アプリ。iPad/Mac用があり、コーディングの知識は不要です。Swiftの言語そのものを選択肢からタップしてコード入力できる点が特徴。段階的に学習を積み上げる初心者にも優しい設計ながらも、正統派のSwiftが学べます。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

解決済

1回答

1046閲覧

UserDefaultsで配列のBool値を保存する方法が知りたいです。

marriageblue

総合スコア3

Swift Playgrounds

Swift Playgroundsは、初心者・子ども向けのSwift学習アプリ。iPad/Mac用があり、コーディングの知識は不要です。Swiftの言語そのものを選択肢からタップしてコード入力できる点が特徴。段階的に学習を積み上げる初心者にも優しい設計ながらも、正統派のSwiftが学べます。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

0クリップ

投稿2022/02/04 17:22

swiftuiでチェックリストを作成したく、
アプリを再起動しても、再起動前にチェックマークをつけた部分にはチェックマークを残しておきたいです。

各Buttonを押したらtextで✔︎をつけて、✔︎の付いている状態をUserDefaultsで保存したいのですが、再起動のたびに✔︎が消えてしまいます。

どのようにすれば解決するか、ご教授いただきたいです。よろしくよろしくお願いいたします。

swift

1 2import SwiftUI 3 4struct ContentView: View { 5 @State private var selections = Set<String>() 6 @State var Save:Bool = false 7 8 var body: some View { 9 List(kyakulist, id: \.self) { row in 10 Button { 11 if selections.contains(row) { 12 selections.remove(row) 13 } else { 14 selections.insert(row) 15 } 16 UserDefaults.standard.set(selections.contains(row), forKey: "row") 17 } label: { 18 HStack { 19 Text("\(row)") 20 if selections.contains(row) { 21 Spacer() 22 Text("✔︎") 23 } 24 } 25 } 26 } 27 .onAppear{ 28 self.Save = true 29 guard let defaults = UserDefaults.standard.value(forKey: "row") as? Bool else { return } 30 self.Save = defaults 31 } 32 } 33} 34 35```swift 36 37```swift 38 39let kyakulist:[String] = [ 40 "みかん", 41 "りんご", 42 "マンゴー", 43 "いちご", 44 "バナナ", 45 "ぶどう", 46 "もも", 47 "ドリアン", 48 "なし", 49 "スイカ", 50 "キウイ", 51 "パイナップル", 52 "グレープフルーツ", 53 "メロン", 54 "さくらんぼ", 55] 56 57```swift

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

配列のBool値を保存する

とのことですが、UserDefaultsにはStringの配列を読み込むためのメソッドがあるようでしたので、こちらのメソッドを使ったイメージで修正してみました。
(selectionsを配列にしてそのまま保存するイメージです)
https://developer.apple.com/documentation/foundation/userdefaults/1416414-stringarray

swift

1 2struct ContentView: View { 3 @State private var selections: Set<String> // = Set<String>() 4 @State var Save:Bool = false 5 6 init() { 7 // 読み込み 8 let array = UserDefaults.standard.stringArray(forKey: "array") ?? [] 9 selections = Set(array) 10 } 11 12 var body: some View { 13 List(kyakulist, id: \.self) { row in 14 Button { 15 if selections.contains(row) { 16 selections.remove(row) 17 } else { 18 selections.insert(row) 19 } 20 // 保存 21 UserDefaults.standard.set(Array(selections), forKey: "array") 22 } label: { 23 HStack { 24 Text("\(row)") 25 if selections.contains(row) { 26 Spacer() 27 Text("✔︎") 28 } 29 } 30 } 31 } 32// .onAppear { 33// self.Save = true 34// guard let defaults = UserDefaults.standard.value(forKey: "row") as ? Bool 35// self.Save = defaults 36// } 37 } 38}

Saveプロパティの意図が読み取れなかったためonAppearはコメントアウトしてしまいました・・

Boolの配列にしたい場合はarray(forKey:)が使えるかもしれません。
https://developer.apple.com/documentation/foundation/userdefaults/1414792-array

その他、参考にしてみた記事です。
https://capibara1969.com/2531/

UserDefaults.synchronize()について
いつの間にか公式ドキュメントにて「使うべきではない」と明示されてました。どうやらiOS12のリリースノートでも告知されていたようですね。なので本記事でも使わないことにします。
ただ、同期が少し遅い気がします。例えばチェックマークをつけて即座にキルすると次回起動時に反映されたりされてなかったりします(TODOの追加、編集、削除も同様です)。手元の環境では大体5秒くらい待てば確実にストレージに保存されてる気がします(僕のコードの問題かもしれませんが・・・)。
https://qiita.com/TheAtlasEngine/items/d95ebbd4b82d47ee844c

投稿2022/02/05 01:21

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

marriageblue

2022/02/05 13:50

ありがとうございます。 無事に意図した挙動にすることができました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問