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

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

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

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

Q&A

解決済

2回答

1826閲覧

変数の値を保持しておく方法

Shun_app

総合スコア1

Swift

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

0グッド

0クリップ

投稿2021/10/16 00:41

前提・実現したいこと

現在クイズアプリを作成しています。
その際に問題出題画面から解答表示画面を問題の出題数が0になるまで行き来します。
その際に、解答表示画面でクイズに正解した場合は正解、間違っていた場合は不正解ボタンを押す仕様になっています。
この時正解ボタンを押した際は正解数変数をインクリメント、不正解ボタンを押した際は不正解数変数をインクリメントするのですが、このインクリメントした変数を保持しておく方法が知りたいため、ご教授いただけないでしょうか。

発生している問題・エラーメッセージ

現時点では変数にあらかじめ初期値として0を入れているのですが、問題出題画面→解答表示画面→問題出題画面→解答表示画面と遷移した際に2回目の回答表示では当たり前ですが、初期値にリセットされてしまいます。
なので、例えば出題数が4問、正解数が4問の場合、結果出力では「正解数:4、不正解:0」としたいのですが、「正解:1、不正解数:0」になってしまいます。

該当のソースコード

Questions.swift //問題出題ファイル ここは特に問題ありません。
Answer.swift //解答出力ファイル @State var correctAnswer = 0 //正解 @State var incorrectAnswer = 0 //不正解 VStack{ HStack{ Button(action:{ numberOfQuestions = numberOfQuestions - 1 correctAnswer = correctAnswer + 1 if numberOfQuestions == 0{ toResultView = true }else{ toTestView = true } }){ Text("正解") } Button(action:{ numberOfQuestions = numberOfQuestions - 1 incorrectAnswer = incorrectAnswer + 1 if numberOfQuestions == 0{ toResultView = true }else{ toTestView = true } }){ Text("不正解") } } }

試したこと

プロパティラッパーなども考えてみたのですが、どのように保持して良いか思いつきませんでした。

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

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

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

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

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

guest

回答2

0

ベストアンサー

score.correctAnswer + 1   // 変更
とありますが、こちらは
score.correctAnswer = score.correctAnswer + 1   // 変更
としなくてもよろしいのでしょうか?

ご提示いただいたscore.correctAnswer = score.correctAnswer + 1で大丈夫だと思います!

次の質問は僕の質問内容の情報不足が原因ですが、
正解ボタンまたは不正解ボタンを押すと出題画面に戻る仕様で、出題画面の解答確認ボタンで解答出力画面にまた遷移するというのを問題の出題数分繰り返します。そして、
スコアを最終的には
NavigationLink(destination: TestFinishView(correctAnswers: score.correctAnswer, incorrectAnswers: score.incorrectAnswer), isActive: $toResultView){
EmptyView()
}
のようにテストの最終結果画面に遷移します。
この時スコアを共有したい場合は
// contentView を読んでいるファイル
TestFinishView()
.environmentObject(Score())  // 追記
が必要になるということでしょうか?
色々勉強不足で申し訳ありません。

この場合(contentView().environmentObject(Score())を指定する)だと、必要ではありません。
.environmentObjectで指定した以降のviewでは@EnvironmentObject var score: Scoreで読み込むことができます。

struct TestFinishView: View { @EnvironmentObject var score: Score // アクセスできるようにする。 var body: some View { Text("現在のスコアは、(score. correctAnswer)です。") // 値を表示 } }

最後に、@EnvironmentObjectが一番簡単なやり方ですがデータ全体を共有してしまうので、それ以外の@StateObjectや@observedobjectなども検討する必要もあるかもしれません。

投稿2021/10/16 06:58

Pomu3270

総合スコア280

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

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

Shun_app

2021/10/16 23:15

ご返信遅くなり申し訳ありません。 ご教授いただいたものを元に実装したところうまくいきました。 大変勉強になりました。 ご回答ありがとうございました!!
Pomu3270

2021/10/18 03:12

お役に立てれてなによりです!!!また何かご機会がありましたら、その都度はよろしくお願いします!
guest

0

@stateだとアクセスは宣言されたView内でしか扱うことができないためです。

一番簡単に実現する方法は、アプリケーション全体でデータを共有することができる@EnvironmentObjectを使うことで実現できます!

Answer.swiftで**@Stateで状態を持つのではなくObservableObjectに準拠したクラスで状態を持つべき**です。
以下例だと、ObservableObjectに準拠したScoreクラスでcorrectAnswerやincorrectAnswerの状態をもつです。

swift

1// 得点を保持するクラス 2class Score: ObservableObject { 3 @Published var correctAnswer = 0 4 @Published var incorrectAnswer = 0 5} 6 7 8 9// 解答出力ファイル 10Answer.swift 11 12 @EnvironmentObject var score: Score // 変更 13 14VStack{ 15 HStack{ 16 Button(action:{ 17 numberOfQuestions = numberOfQuestions - 1 18 score.correctAnswer + 1   // 変更 19 20 if numberOfQuestions == 0{ 21 toResultView = true 22 }else{ 23 toTestView = true 24 } 25 }){ 26 Text("正解") 27 } 28 29 Button(action:{ 30 numberOfQuestions = numberOfQuestions - 1 31 score.incorrectAnswer + 1  // // 変更 32 33 if numberOfQuestions == 0{ 34 toResultView = true 35 }else{ 36 toTestView = true 37 } 38 }){ 39 Text("不正解") 40 } 41 } 42} 43 44 45 46// contentView を読んでいるファイル 47ContentView() 48 .environmentObject(Score())  // 追記

投稿2021/10/16 03:21

Pomu3270

総合スコア280

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

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

Shun_app

2021/10/16 05:45 編集

ご回答ありがとうございます! 少し追加質問させてください。 score.correctAnswer + 1   // 変更 とありますが、こちらは score.correctAnswer = score.correctAnswer + 1   // 変更 としなくてもよろしいのでしょうか? 次の質問は僕の質問内容の情報不足が原因ですが、 正解ボタンまたは不正解ボタンを押すと出題画面に戻る仕様で、出題画面の解答確認ボタンで解答出力画面にまた遷移するというのを問題の出題数分繰り返します。そして、 スコアを最終的には NavigationLink(destination: TestFinishView(correctAnswers: score.correctAnswer, incorrectAnswers: score.incorrectAnswer), isActive: $toResultView){ EmptyView() } のようにテストの最終結果画面に遷移します。 この時スコアを共有したい場合は // contentView を読んでいるファイル TestFinishView() .environmentObject(Score())  // 追記 が必要になるということでしょうか? 色々勉強不足で申し訳ありません。 ご教授お願いします。
Pomu3270

2021/10/16 06:59

> score.correctAnswer + 1   // 変更 > とありますが、こちらは > score.correctAnswer = score.correctAnswer + 1   // 変更 > としなくてもよろしいのでしょうか? ご提示いただいた``` score.correctAnswer = score.correctAnswer + 1 ```で大丈夫だと思います! > 次の質問は僕の質問内容の情報不足が原因ですが、 > 正解ボタンまたは不正解ボタンを押すと出題画面に戻る仕様で、出題画面の解答確認ボタンで解答出力画面にまた遷移するというのを問題の出題数分繰り返します。そして、 > スコアを最終的には > NavigationLink(destination: TestFinishView(correctAnswers: score.correctAnswer, incorrectAnswers: score.incorrectAnswer), isActive: $toResultView){ > EmptyView() > } > のようにテストの最終結果画面に遷移します。 > この時スコアを共有したい場合は > // contentView を読んでいるファイル > TestFinishView() > .environmentObject(Score())  // 追記 > が必要になるということでしょうか? > 色々勉強不足で申し訳ありません。 この場合(contentView().environmentObject(Score())を指定する)だと、必要ではありません。 .environmentObjectで指定した以降のviewでは``` @EnvironmentObject var score: Score ```で読み込むことができます。 ``` struct TestFinishView: View { @EnvironmentObject var score: Score // アクセスできるようにする。 var body: some View { Text("現在のスコアは、(score. correctAnswer)です。") // 値を表示 } } ``` 最後に、@EnvironmentObjectが一番簡単なやり方ですがデータ全体を共有してしまうので、それ以外の@StateObjectや@observedobjectなども検討する必要もあるかもしれません。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問